Design by Contract - PowerPoint PPT Presentation

Design by Contract. Design by Contract. Design by contract is the process of developing software based on the notion of contracts between objects, which are expressed as assertions . . Design by Contract.

Copyright Complaint Adult Content Flag as Inappropriate

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

Download Presentation

PowerPoint Slideshow about ' Design by Contract' - mara-poole

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

Object oriented software development builds on this familiarity by providing atraceable path from real-world objects through their conceptualisation during analysisand their construction during design, to their use during implementation. In the end, theobjects that you implement become the software system.

One way to ensure that a software systemperforms its intended functions is based on the concept ofa contract. When an object sends a message to another object, a form of contract exists.The receiver is being asked to perform a service for the sender. The senderis viewed as a client that requests a service from a supplier (the receiver or server). Whenever aservice is provided, a contract comes into play: the client expects the supplier toperform the service correctly and the supplier expects to be asked to perform onlythose services it knows how to supply.

If either of these expectations is not met, thecontract has been broken. Identifying roles in terms of clients and suppliers (servers) enables designers to specify theresponsibilities of objects more precisely; this allows clearer software to be builtwhich, in turn, leads to greater confidence in the correctness of the software i.e.the users’ requirements are being met. The process of developing software based on contract between objectshas come to be known as Design by Contract.

Use cases provide a language for describing requirements that aim to beunderstandable to both technical (developers) and non-technical (customers and users)people. A significant part of a use case consists of the pre-condition and post-conditionthat constrain it. Pre-conditions, post-conditions and invariants are collectively knownas assertions. These can be used to build contracts.

To the customer (or software purchaser) many assertions will appear as business rules.

A scenario is a description of a sequence of actions that illustrate a piece ofinteresting behaviour. Just as an object is an instance of a class, a scenario is said toan instance of a use case. In the UML, a scenario describes the interaction anddialogue between the users of a software system (its actors) and the software systemitself. For a given use case, we expect to see one main scenario that describes the flowof events leading to a successful conclusion. There may be other scenarios thatdescribe alternative or additions to the main scenario.

Assertions can be introduced early in the developmentprocess, during analysis as contract on use cases. As development progresses so the assertions will be refinedwith more detail being added and carried through into design and then into implementation.

Assertions can be included in the final code to be checked both by thecompiler and by the run-time system. Ultimately, the contract is embodied in the codeand we have a traceable pathway from analysis to implementation that shows how theassertions were developed and relates the code directly to the requirements. Thisprocess is known as Design by Contract or DbC for short.

In the general case: a supplier’s services will still satisfy a request if their constraints on inputs (pre-conditions) are a slackening (DbC calls it weakening) of the requirements on inputs, and/or their constraints on outputs (post-conditions) are a tightening (DbC calls it strengthening) of the requirements on outputs.

3 assertions provide a way of controlling inheritance in which substitutability and redefinition of methods are allowed;

4 provided the programming language has an exception mechanism that accords with the principles of DbC, assertions together with the exception mechanism can be an important aid to developing mission critical systems.

The aim is to describe the state changes required of an operation, activity or task without having to say how they might be achieved. Each contract tells you about the constraints on the expected behaviour of an operation. In effect, the design can be deferred while you focus on what must happen.

In the context of software development, a contract is between two objects: the client object and the supplier object. The contract comes into effect when the client uses one of the services that the supplier object provides. Since the client object wants the server object to do something for it, you can view this relationship as a contract, similar to the one we looked at above, with conditions on inputs (pre-conditions) and outputs (post-conditions).

As an example of how a contract works, consider a bank account system in which there is a method for withdrawing an amount of cash from an account. If there is a limit on the amount by which the account can be overdrawn, we can specify what the method should achieve and what should be true before the method should be invoked, as a contract with the following pre- and post-conditions:

pre-condition: there must be sufficient funds in the account;

post-condition: the account will have been debited by the requested amount.

that the pre-condition must be satisfied means the client must ensure that there are sufficient funds in the account for the amount to be debited, but the supplier does not need to check that there are sufficient funds (if the pre-condition is not satisfied, the client cannot expect to get the service it would like);

that the post-condition must be satisfied means the supplier must debit the amount from the account, and the client receives the service that it requires. (supplier incorrect.)

The generalization relationship requires the use of the substitutability test to determine whether one object was a generalization of another: if an object of one type can be substituted for an object of another type in all circumstances, the type of the first object is a subtype of the second; that is, the second object is a generalization of the first.

If the objects of the subclasses are to be substitutable for those of the parent class, a certain relationship must hold. This relationship can be expressed in terms of the pre- and post-conditions associated with the overridden methods in the two classes.

Promise no less: any assumptions which were valid when the superclass’s implementation was used should still be valid for the subclass implementation. Therefore the subclass’s post-conditions must be at least as strong as the superclasses post-conditions.

In an OO system, pre- and post-conditions can be relatedto a client–supplier contract between objects and how they can be usefully employedin the process known as DbC. Part of the value of DbC was that it allowed traceability fromrequirements through to code.

We need an initial encoding ofrequirements as assertions. These must be transformed into assertions aboutcode. DbC can improve the documentation of classes, but linking these requirement and code assertions.

Assertions are used for a different purpose: they are ways of describing the conditions under which software elements will and will not work (pre-conditions) and the conditions that they will achieve (post-conditions). If the supplier and its clients are correct, that is, keep to their contract, assertions should always evaluate to true. In other words, an assertion violation, which would be detected at run-time, is an indication of a defect in the software.

The use of precisely defined contracts clearly assigns all responsibilities to either the client or the supplier. The stronger the pre-condition, that is, the more restrictive it is, the higher the burden on the client (there are more conditions to be satisfied before the client is allowed to invoke the supplier) but the easier it makes the task of the supplier. In practice, it has been found that designs that concentrate on doing a well-defined job are more successful than those that try to handle too many cases. In terms of pre-conditions, this implies that stronger pre-conditions are better than weak ones. Note that this strengthening needs to be balanced with the benefits that accrue from the weakening of pre-conditions e.g. easier to use?

What does this mean for behaviour of a subclass? Overridden methods must conceptually do the same job as the method in the superclass.

Demand no more: a subclass must accept any message and arguments that the superclass accepts. Therefore a subclass preconditions must be no stronger than that of the superclass. (Roughly: should not “turn off” inheritance)

Promise no less: any assumptions which were valid when the superclass’s implementation was used should still be valid for the subclass implementation. Therefore the subclass’s post-conditions must be at least as strong as the superclasses post-conditions. (Roughly: inheritance is strict extension not a reduction)

The is-a relationship is a way ofdetermining when the concepts behind the classes are related through inheritance. For a subclass to be a subtype, each instance of it must respond tothe ‘same operations’ as instantiations of the superclass.

Clients are responsible for ensuring preconditions are met, they can assume the post-conditions hold after the operation has been performed providing the preconditions are met.

Supplier can assume that the pre-condition hold if they trust the client. It is also responsible for ensuring post-condition hold if the pre-condition are met. It must ensure that the invariant holds when an object is created and after every method call on that object.

1) traceability of assertions from analysis to implementation allows the developer to associate runtime activities or errors with design artefacts, hence a runtime error may be traceable to a design decision or design refinement. (a use case).

2) a (semi) formal way of stating correctness, the implementation respects the invariants, pre/post conditions in the specification. This can be agreed upon by both developer and client to be correct with respect to the specification.

Using design by contract means that assertions can be introduced early in the development process, during analysis.

As development progresses so the assertions will be refined with more detail being added. Assertions can be carried through into design and then into implementation.

Importantly, assertions can be included in the final code to be checked both by the compiler and by the run-time system.

Ultimately, the contract is embodied in the code and we have a traceable pathway from analysis to implementation that shows how the assertions were developed and relates the code directly to the requirements.

At the implementation level, if the software representing the client and supplier meets its contract we can say that the software is correct with respect to its specification.

A subclass is supposed to be able to fulfil the contract entered into by the superclass.

An object of a class subclass should be substitutable for an object of the superclass.

An object of a subclass is supposed to be usable everywhere that the superclass is.

If the subclass is supposed to be able to fulfil the contract entered into by the superclassthen the overridden methods must conceptually do the same job.

Assertions implemented in hierarchies should obey the following rule:

Demand no more: promise no less.

Demand no more: a subclass must accept any message and arguments that the superclass accepts. Therefore a subclass preconditions must be no stronger than that of the superclass.

Promise no less any assumptions which were valid when the superclass’s implementation was used should still be valid for the subclass implementation. Therefore the subclass’s post-conditions must be at least as strong as the superclasses post-conditions.

The overridden method may "weaken the precondition and strengthen the postcondition".

The preconditions for the subclass method are logical or-ed with the super class preconditions.

The postconditions are logical and-ed.

This requires that the subclass accept all input valid to the super class method, and may accept more that is invalid to the super class. However, it must abide by the guarantees made by its parent, though it is given the option of strengthening those guarantees

An important consequence of the Design by Contract theory is to yield a better understanding of the central object-oriented notions of inheritance, polymorphism, redefinition and dynamic binding. A class B which inherits from a class A may provide a new declaration for a certain inherited feature r of A. For example a specialized implementation of DICTIONARY might redefine the algorithm for put. Such redefinitions are potentially dangerous, however, as the redefined version could in principle have a completely different semantics. This is particularly worrisome in the presence of polymorphism, which means that in the call

the target a of the call, although declared statically of type A, could in fact be attached at run time to an object of type B. Then dynamic binding implies that the B version of r will be called in such a case.

This is a form of subcontracting: A subcontracts r to B for targets of the corresponding type. But a subcontractor must be bound by the original contract. A client which executes a call under the form

if a.pre then a.r end

must be guaranteed the contractually promised result: the call will be correctly executed since the precondition is satisfied (assuming that pre implies the precondition of r); and on exit a.post will be true, where post is the postcondition of r.

These observations shed light on the true significance of inheritance: not just a reuse, subtyping and classification mechanism, but a way to ensure compatible semantics by other means. They also provide useful guidance as to how to use inheritance properly.