Previous Table of Contents Next


It is also useful, as in any design, to list some of what is not present in Eiffel. The approach is indeed based on a small number of coherent concepts so that it remains easy to master. Eiffel typically takes a few hours to a few days to learn, and users seldom need to return to the reference manual once they have understood the basic concepts. In fact, the description given in this chapter is, save for a few details, essentially complete. Part of this simplicity results from the explicit decision to exclude a number of possible facilities:

  No global variables, which would break the modularity of systems and hamper extendibility, reusability, and reliability.
  No union types (or record type with variants), which force the explicit enumeration of all variants; in contrast, inheritance is an open mechanism that permits the addition of variants at any time without changing existing code.
  No in-class overloading which, by assigning the same name to different features within a single context, can cause confusion, errors, and conflicts with object-oriented mechanisms such as dynamic binding. (Dynamic binding itself is a powerful form of interclass overloading without any of these dangers.)
  No goto instructions or similar control structures (break, exit, or multiple-exit loops), which break the simplicity of the control flow and make it harder or impossible to reason about the software (in particular through loop invariants and variants).
  No exceptions to the type rules. To be credible, one type system must not allow unchecked casts converting from one type to another. (Safe cast-like operations are available through assignment attempt.)
  No side-effect expression operators confusing computation and modification.
  No low-level pointers and no pointer arithmetic, a well-known source of bugs. (There is, however, a type POINTER with no available operations except assignment, comparison, copying, and argument passing, used solely for interfacing Eiffel with C and other languages.)

9.3. The Software Process in Eiffel

Eiffel, as noted, supports the entire lifecycle. The underlying view of the system development lifecycle is radically different not only from the traditional Waterfall model (implying a sequence of discrete steps, such as analysis, global design, detailed design, and implementation, separated by major changes of method and notation) but also from its more recent variants such as the spiral model or rapid prototyping, which remains predicated on a synchronous, full-product process and retains the gaps between successive steps.

Clearly, not everyone using Eiffel will follow to the letter the principles outlined in this chapter; in fact, some competent and successful Eiffel developers may disagree with some of them and prefer a somewhat different process model. In the author’s mind, however, these principles fit best with the language and the rest of the method, even if practical developments may fall short of applying their ideal form.

9.3.1. Clusters and the Cluster Model

Unlike earlier approaches, the Eiffel model assumes that the system is divided into a number of subsystems or clusters. It keeps from the Waterfall a sequential approach to the development of each cluster (without the gaps) but promotes concurrent engineering for the overall process, as suggested by Figure 9.1.


FIGURE 9.1.  The cluster model: sequential and concurrent engineering.

The Eiffel techniques developed in this chapter, in particular information hiding and design by contract, make the concurrent engineering process possible by letting the clusters rely on other clusters through clearly defined interfaces, strictly limiting the amount of knowledge that must be acquired about a cluster to use it, and permitting separate testing. When the inevitable surprises of a project happen, the project leader can take advantage of the model’s flexibility, advancing or delaying various clusters and steps through dynamic reallocation of resources.

Each of the individual cluster lifecycles is based on a continuous progression of activities, from the more abstract to the more implementation-oriented, as shown in Figure 9.2.


FIGURE 9.2.  The individual cluster lifecycle.

Figure 9.2 should be understood as describing a process of accretion (as with a stalactite), where each steps enriches the results of the previous one. Unlike traditional views, which emphasize the multiplicity of software products—analysis document, global and detailed design documents, program, and maintenance reports—the principle here is to treat the software as a single product that is repeatedly refined, extended, and improved. The Eiffel language supports this view by providing high-level notations that can be used throughout the lifecycle, from the most general and software-independent activities of system modeling to the most exacting details of implementation tuned for optimal runtime performance.

These properties make Eiffel span the scope of both object-oriented methods (whereas most such methods do not yield an executable result) and programming languages (whereas most such languages are not suitable for design and analysis).

9.3.2. Seamlessness and Reversibility

The preceding ideas define the seamless approach embodied by Eiffel. With seamlessness goes reversibility: the ability to go back, even late in the process, to earlier stages. Because the developers work on a single product, they can take advantages of bouts of late wisdom—such as a great idea for adding a new function, discovered only at implementation time—and integrate them in the product. Traditional approaches tend to discourage reversibility because it is difficult to guarantee that the analysis and design will be updated with the late changes. With the single-product principle, this is much easier to achieve.

Seamlessness and reversibility enhance extendibility by providing a direct mapping from the structure of the solution to the structure of the problem description, making it much easier to take care of customers’ change requests quickly and efficiently. They promote reliability by avoiding possible misunderstandings between customers’ and developers’ views. They are obviously a major boost to maintainability. More generally, they yield a smooth, consistent software process that is particularly favorable to both quality and productivity.


Previous Table of Contents Next