Friday, April 20, 2007

What is (in) a Contract?

In component-based and service-oriented systems interfaces represent the core means for describing the boundary of the provider and consumer of a particular, semantically-related aggregation of functionality. In object-oriented systems these interfaces are typically message-based or method-based. Contracts help specifying the properties of such boundaries. Basically, they define constraints, properties, rules and other details that have to be considered when something is crossing the boundary. The most relevant part of the contract are rules defining which messages are permitted to be sent to a message-based interface or what methods might be called on a method-based interface. Obviously, everything returned from the provider (results or faults) to the consumer must also be expressed in terms of the contract. Constraints may define how messages are structured and what parts they contain. It is noteworthy that a contract does not just comprise syntactic sugar but may also specify semantics such as the order of message exchange or method invocations, pre- and postconditions, or even operational qualities like security or performance hehavior. For example, a contract may specify that calling a specific interface method only takes a specific amount of time. The order of method invocations could also be an ingredient of the contract such as the rule: "before invoking read(), you need to invoke open()". Same holds for messsage-based interface where a state machine might define the order and kind of message exchanges. In addition, a contract could contain infrastructural information. E.g.: Which kind of protocol may be used for accessing the interface? Or the location of the implementation artifact! A contract may also include relationships between interfaces such as the required interfaces a component needs or expects from other components.
There is another dimension of contracts. Contracts might be explicit or implicit. In the former case we need description languages to express the contract, while in the latter case contracts are either part of the infrastructure (such as a programming language) or implicitly hard-coded into application functionality.
In contracts we also may find different restrictions for different stakeholders. Think of a C++ class with private, protected and public sections. Depending on whether you subclass or use a class, you might experience more or less access restrictions.
In distributed systems contracts are ubiquitious. Think of EJB with its deployment contracts, component/container contracts, or client/component contracts and think of SOA platforms!
As we recognize, contracts are much more complex and important than we tend to believe.
Why - in the hell - are contracts relevant for softwae architecture? They are essential as they define various essential aspects when dealing with the boundaries of a particular entity such as a service or component. Contracts define the interactions that may take place between the service or components and their clients as well as the qualities and constraints associated with these interactions. Only if there are formal contract descriptions, tools can help with the (automatic) composition of artifacts (e.g., MDSD) as well as with the validation of architectures and implementations.
If you are going to model a new system, keep in mind to describe the contracts of the interfaces introduced. Otherwise, developers or architects won't be able to understand how to access this interface in a proper way. A surprisingly large amount of problems in software engineering is caused by missing or incomplete or inconsistent contracts. Hardware developers won't ever build any system without knowing the contracts of the system constituents a.k.a. specifications. Why should we as software engineers? Don't believe in statements like "contracts are for pussies". Only contract-based development leads to high-quality architectures and implementations.

1 comment:

Eric said...

You are taking the words out of my mouth. We at McGill and Oxford universities have been developing "tracematches" over the past years now (see http://abc.comlab.ox.ac.uk/papers#oopsla2005). Those actually allow you to define contracts over the order in which events should occur, e.g. methods should be invoked. It's pretty nice because it's really explicit and declarative.

The hard problem is checking those properties statically or at least efficiently at runtime. We have recently looked a lot into those issues and made quite some progress. So maybe you find this work interesting (all on our website).