FREE Subscription to Dr. Dobb’s Digest: Same Great Content, New Digital Edition
Site Archive (Complete)
Email
Print
Reprint

add to:
Del.icio.us
Digg
Google
Furl
Slashdot
Y! MyWeb
Blink
July 01, 2000
Contracts for Components Interface Definition

Bertrand Meyer
Interface Definition Languages as we know them today are doomed.
July 2000: Beyond Objects: Contracts for Components Interface Definition

It’s sometimes only after a technology has established itself that one can start to understand what it is really about. In the case of component-based development, I hope that we can do better. We three columnists (Bruce Powel Douglass, Clemens Szyperski and I) are trying, with our individual voices, backgrounds and interests, to analyze and influence the technology as it happens. Since we are active participants in the field rather than dispassionate observers, we have a vested interest in ensuring that component-based development evolves correctly and fulfills its promises. As I have hinted in earlier installations, one of the incontrovertible conditions is that we properly tackle the issue of specifying components. The word "contract" has already been tossed out a few times in this respect (by myself as well as by Szyperski and Douglass), and it’s time to examine more closely what contracts mean for components.

Component-based development is still very new, but we are starting to have enough perspective to see what it’s about. Components as they exist today result, I believe, from the confluence of two major developments of the 1990s: the gradual recognition in the software engineering community that object technology is the sine qua non of any serious development, and the success of visual controls, as first popularized by Visual Basic and Delphi, in the programming trenches.

(I must also mention a third phenomenon without which none of this would have happened: the general trend toward standardization of interfaces, most visibly through the universal deployment of the Windows API–Linux’s potential notwithstanding. Because this is the background for much of the computer industry’s extraordinary recent development, we don’t need to delve into it further.)

The major component standards–COM, CORBA and EJB–attempt to capitalize on the power of object-oriented principles to generalize "controls" to full-fledged software components, similar in spirit to the tangible components of other engineering disciplines (electronics, machinery and so on), and applicable to any software need, not just user interfaces. What is still missing in this effort, however, is a standard way to specify the components.

The Pipe and the Painting

In Component Software (Addison-Wesley, 1998), Clemens Szyperski rightly points out that software components differ in intrinsic ways from engineering components in, for example, electronics. These differences are natural, since the analogy with electronics is only a metaphor, and not all properties from one field apply to the other. A metaphor is not an identity. However, one property of components does apply to any field of engineering: We cannot seriously have component-based development without developing, for every component, a specification of the component that is distinct from the component itself and serves as the sole basis for users ("clients") of the component.

Why is this rule, so obvious in all other fields, not universally applied in software? The answer lies in the specific nature of software and the uncertainty that it creates between the description and what is described. The just-stated requirement that the specification should be "distinct from the component itself" is merely a platitude in electronics or construction engineering: No one would confuse a circuit with a circuit diagram or a bridge with a map of the bridge. You can fall from the bridge, but not from the map, and you won’t get an electric shock from the circuit diagram. Remember the famous Magritte painting of a pipe, entitled "Ceci n’est pas une pipe" (This is not a pipe). With software, the platitude loses its validity, because separating specification from implementation is not that straightforward anymore. Otherwise, during design discussions we wouldn’t be screaming "but this is only an implementation matter!" at each other. And information hiding wouldn’t be such a key issue.

In my first column ("The Significance of Components," Oct. 1999), I cited information hiding as the key determinant in the appeal of binary component standards and noted that binary components make information hiding inevitable. But information hiding, and any decently formed component, can only work with a specification. You can only trust components to the extent that you know what they do, and this is where current approaches don’t quite deliver yet.

Interface Definition Languages

Both the CORBA and COM standards use, as one of their central concepts, an Interface Definition Language. It’s a bit confusing because they use the same name and acronym, IDL, for two distinct languages. But this shouldn’t bother us here, because the two IDLs are conceptually quite close. If you don’t know IDL (in either variant), you in fact do if you know C++, since an IDL class specification is very similar to a C++ header file–the part that gives the signature of the operations, without their implementations. For example, here is a CORBA IDL specification of a function from a component in charge of making airplane reservations:

boolean ReserveFlight (in Seats places) raises (InvalidSeat, SeatAlreadyBooked);

The specification says that the component offers an operation ReserveFlight that expects as argument a list of seats to be reserved, returns a boolean value (while this is presumably an indication of success, I would never use such side-effect-producing functions; this example does illustrate the prevalent programming style, however), and may raise certain exceptions in case things don’t go as smoothly as we would like.

Studying current IDLs leads to two immediate points. The first is that IDLs as we know them today are doomed. The notion of interface isn’t doomed, but the idea that you should write an interface as a separate effort is. It may work for a few stable components, but in the long term this is a broken approach for at least two reasons.

First, software will change. We need mechanisms to help us avoid updating a component and forgetting to update its official specification (and conversely).

Second, much of the information about a component can and should be expressed in the text of the component itself, where it complements the component’s implementation-specific properties. Aside from the problem of ensuring compatibility in case either aspect (specification and implementation) changes, it is not realistic in the long term to ask component developers to write the specification properties twice. This is the "Self-Documentation Principle" that I discuss in Object-Oriented Software Construction, Second edition (Prentice Hall, 1997). It is thoroughly applied in Eiffel where class documentation is entirely extracted by software tools, from the class text. Javadoc follows from the similar principles.

This is why the standard CORBA approach of writing an IDL specification and using an IDL compiler to generate a module template in a programming language seems backward. You should concentrate on writing the software and let the tool produce its interfaces. This rule is not affected by the observation that, in most cases, you can’t extract a class from a normal OO system and make it into a component, but instead, you must write a few interface classes to serve as your application’s component façade to the rest of the world. Even so, you will want to write your façade classes in your programming language of choice, not in yet another formalism.

A number of CORBA tools are now available to do just that–decompilation into IDL. In the COM world, ISE’s EiffelCOM wizard (http://eiffel.com/products/com) enables you interactively to wrap Eiffel applications into COM components, and other languages’ COM components into Eiffel façades for use from Eiffel. It seems clear, anyway, that the evolution of COM technologies, as will be described in my next column, will move away from IDL as something that must be coded separately.

What Is a Spec?

Separateness is not the only problem of the current IDLs. Their most striking limitation has been mentioned in earlier columns: They stay within the limits of purely structural specifications. The above specification of ReserveFlight says little in terms of actual semantic specifications. It gives the name of the operation all right, the number and types of its arguments and the list of abnormal cases it is prepared to encounter and signal, but reveals nothing about what it actually does.

Yet this is what we would expect from a specification in the full sense of the term. An electrical component’s specification will tell us about global operating conditions (temperature and so on), acceptable input signals (voltage and amperage limits) and output signals as a function of the input–all independently of the specific implementation technology. We need the same three kinds of specification elements for a software component:

• The class invariant, describing global constraints. For example, "The total number of allocated seats is always positive and no greater than the physical number of seats plus overbooking allowance." This is particularly important in stateful components, since states usually must satisfy some consistency constraints. (I know that Szyperski doesn’t think components should have states, but this is not a universal view, and if states make things harder to manage, as he rightly implies, that is even more reason to require good conceptual tools to keep them in control.)

• The operation precondition, describing constraints on calling the operation, such as "Only use this for a flight that hasn’t already taken off."

• The operation postcondition, describing expected properties of the result, such as "If the booking was successful, all the seats requested must now be considered reserved."

These concepts of Design by Contract have been extensively applied to the development of object-oriented software in Eiffel, where they are part of the basic fabric of the language and are increasingly being applied to other approaches such as Java (through tools such as iContract), C++ (through macro packages like Nana) and the Unified Modeling Language (through the Object Constraint Language). For links to references on these tools and many others, see the Design by Contract portal described in the sidebar.

The concepts are even more necessary in connection with component standards such as CORBA, COM and EJB since, as I pointed out in an earlier column, "it’s information hiding, stupid." With binary components, we don’t have the last resort of going to the source code. Yet such a specification is badly lacking in this respect. The closest it comes to specifying the semantics is by listing the exceptions. But this leads to a programming style heavily based on exception handling, which is not healthy; and, of course, it is rather paradoxical that we should specify to our clients what abnormal conditions can arise but not take the trouble to tell them what the normal expected behavior is!

A number of proposals have been made to add contracts to CORBA and COM (again, visit www.designbycontract.com for pointers). We are currently building a language-independent contract framework for COM.

As Szyperski hinted in a recent column, transposing the notion of contract from the world of classical programming to the world of component-based development raises a few challenges:

• In a development environment such as Eiffel, iContract or Nana, we may expect to use contract monitoring for development, then turn it off for execution. With components, we may have to keep contract verification on all the time.

• The very semantics of contracts changes in a concurrent, development environment. In the OOSC book, I discuss at length the SCOOP model (Simple Concurrent Object-Oriented Programming), which fundamentally relies on contracts but with preconditions reinterpreted as wait conditions (in fact, the basic synchronization mechanism) rather than as correctness conditions.

• The expressiveness of the contract language is important. There has been much progress recently in this area, with such developments as the Object Constraint Language (OCL) for UML and new high-level contract-oriented mechanisms for Eiffel, described in my June 2000 column in The Journal of Object-Oriented Programming ("Towards More Expressive Contracts").

• There may be more than only one level of contractual properties.

On the last point, my colleagues Christine Mingins and Jean-Marc Jézéquel (whom I plan to invite to contribute a guest column later in this series) distinguish four levels of contracting: basic type contracts, such as exist in typed programming languages as well as the current IDLs; semantic contracts, such as the ones cited above, expressing invariants, preconditions and postconditions; performance contracts, so critical for example in real-time applications; and quality-of-service contracts, harder to quantify but just as important in practice, as anyone who has tried to access his E*Trade account at the time of highest market volatility will have noted.

The general idea of the Trusted Components effort (http://www.trustedcomponents.org) is to discover whether we can build a repertoire of high-quality components–components to which we can really entrust the reliability of our applications.

The difficulty of these issues explains why I haven’t yet included in the present column a description of my proposed CDL (Contract Definition Language) as announced in the previous installment. I realized that this was still premature; we need first to explore the background in some depth. Later columns will continue in this direction, and will at due point include the CDL proposal.

The Three Questions of Contracting

In the meantime, it is essential to note that no good component can exist without a good specification. Even if you do not have access to languages and tools officially supporting the Design by Contract methodology, it’s time to start using the principles. The good news is that it’s not difficult. We are not talking about fully formal approaches, such as Jean-Raymond Abrial’s B method and tools, described in his B Book (Cambridge University Press, 1996–surgeon general’s warning: less gripping than a typical Stephen King novel, and not for the mathematically faint of heart), and used recently to prove, mathematically, the correctness of the security aspects of the latest, driver-less line of the Paris metro, a 100,000-line program.

For most of us, this is still beyond our reach. We are talking about something much simpler–the three questions. In Design by Contract we keep asking: What does it maintain? What does it expect? What does it guarantee? You will, of course, have recognized in these questions the notions of class invariant, operation precondition and operation postcondition.

Don’t ever write any component, in any sense of the term (whether you favor the broader sense, which Bruce Powel Douglass and I advocate, or Clemens Szyperski’s narrower definition), without asking the Three Questions of Software Contracting. Component-based development, and just good software development, comes at that small price.

TOP 5 ARTICLES
No Top Articles.
DR. DOBB'S CAREER CENTER
Ready to take that job and shove it? open | close
Search jobs on Dr. Dobb's TechCareers
Function:

Keyword(s):

State:  
  • Post Your Resume
  • Employers Area
  • News & Features
  • Blogs & Forums
  • Career Resources

    Browse By:
    Location | Employer | City
  • Most Recent Posts:
    MEDIA CENTER  more
    NetSeminar
    Modernize your Development by Moving Build and Code Quality Upstream
    Moderated by Jon Erickson, Editor-in-Chief of Dr. Dobb's, this interactive panel discussion brings industry experts Anders Wallgren, CTO of Electric Cloud and Gwyn Fisher, CTO of Klocwork together for a candid discussion of the cost savings, productivity and quality benefits that can be achieved by stabilizing builds and code quality as early in the development cycle as possible.

    The reality of today's development environment - geographically distributed teams, the use of Agile development practices, increasing application complexity, etc. - is straining the viability of the traditional coding, build and release process. To stay ahead of the curve, development teams are modernizing their approach to dealing with these issues, and as a result are achieving new levels of development productivity. Register for the webcast.
    Date: Wednesday, July 15, 2009
    Time: 11 am PT/2 pm ET
    Modernize your Development by Moving Build and Code Quality Upstream
    Moderated by Jon Erickson, Editor-in-Chief of Dr. Dobb's, this interactive panel discussion brings industry experts Anders Wallgren, CTO of Electric Cloud and Gwyn Fisher, CTO of Klocwork together for a candid discussion of the cost savings, productivity and quality benefits that can be achieved by stabilizing builds and code quality as early in the development cycle as possible.

    The reality of today's development environment - geographically distributed teams, the use of Agile development practices, increasing application complexity, etc. - is straining the viability of the traditional coding, build and release process. To stay ahead of the curve, development teams are modernizing their approach to dealing with these issues, and as a result are achieving new levels of development productivity. Register for the webcast.
    Date: Wednesday, July 15, 2009
    Time: 11 am PT/2 pm ET
                                   
    INFO-LINK

    Resource Links: