Dr. Dobb's Journal June 2000
Metis is an object-oriented development methodology that includes all the usual tasks found in a generic software project lifecycle, as well as the often forgotten ones such as user interface or database design -- all together distributed across a truly evolutive lifecycle. In designing Metis, our goal at Neco (http://www.neco-ti.com/) was to produce a general-purpose methodology with a sound theoretical background capable of giving support for the number of practical issues that arise during many software-development projects. We developed Metis in a similar way as a software project. The daily work in real software projects during the last year was managed using the most recent release of Metis and, as a result, it produced feedback in the form of validation and new requirements.
We started the Metis project by adopting the Fusion method as described by D. Coleman et al., in Object-Oriented Development: The Fusion Method (Prentice-Hall, 1994). Later on, the methodology evolved into an adapted fusion method (in Spanish, "Método Fusion Adaptado" or MFA). One of the main features of the MFA was a decrease of formality as compared with the Fusion method itself, in order to make it a little more practical. Eventually, the need to improve the MFA to better serve in information-systems development became clear. It was that effort that made Metis evolve into its current state.
Metis takes into account a number of areas often considered part of the development process, but included at the notational and procedural level by few or no methodologies at all. These areas include:
As we have said, Metis was designed as a modular system for the same reasons that make modular software systems more correct, robust, and extensible than monolithic ones (see Object-Oriented Software Construction, Second Edition, by Bertrand Meyer, Prentice Hall, 1997). In fact, Metis is designed around different components and interfaces between them. Metis components are usually functions (modeling, requirements gathering, coding, change control, and so on) and results (models, plannings, programs, and the like), the latter often expressed as documents (diagrams, pseudocode, sketches, and so on). Interfaces among different components are defined by the relationships between functions and results; for example, high-level modeling creates class diagrams that are used by planning and low-level modeling.
The most practical manifestation of modularity in Metis comes when customizing the methodology for a new project. Metis does not provide a fixed sequence of phases, but rather it provides a set of functions that can be performed in any order that satisfies the interface constraints. A good example can be useful: The high-level analysis phase in a typical project often raises new needs. "Needs" is one of Metis results, and Requirements Gathering is one of Metis functions which take as input argument a set of such needs. So it may be right to perform a requirements gathering function after the mentioned high-level analysis. (In fact, this requirements gathering phase signals the beginning of a new lifecycle, perhaps corresponding to a subsystem of the main system to be developed.)
Modularity in Metis also lets users plug in functions and results suitable to specific development needs, or even develop their own functions and results. For example, a Persistent Storage Design function can be inserted in the project's lifecycle if the systems are using a database, but left out of the way if none is needed. A number of optional functions have been developed for Metis, including Persistent Storage Design, User Documentation, Change Control Management, and System Measuring. Any of these functions can be inserted where its interface matches with that of the environment.
The use of the same concepts from the beginning until the end is a widely documented property of object-oriented development (see A Book of Object-Oriented Knowledge, by B. Henderson-Sellers, Prentice Hall, 1992, for example) as with the class concept. However, as the Fusion method exemplifies, the level of detail of the class concept during analysis is different from its level of detail during design or implementation. We decided to formalize these concepts and make them explicit for the development process, adopting the stereotype term from UML. The main use of stereotypes is to express the terms in which models can be built, and set up the foundation for effective communication among developers and between developers and computer tools. For example, we can decide that analysis must be performed around the stereotype's class, attribute, and relationship, so everybody knows what those concepts mean and which properties they have. If modeling needs cannot be satisfied by the available stereotypes, new ones should be introduced by subclassing the existing ones or otherwise introducing new conceptual constructs.
Almost every methodology clearly states that analysis must be performed around classes and relationships, but very few describe what stereotypes must be used during low-level activities such as detailed design. Although some semantic additions have been proposed (see Object-Oriented Development at Work: Fusion in the Real World, edited by R. Malan, et al., Prentice Hall, 1996), more stereotypes are needed for those activities. For example, threads and processes are very useful during operations design, as well as user-interface elements and service states, which can be used to model user interaction.
The set of stereotypes available during development can change in two ways. First, stereotypes can be made available or unavailable depending on the function being performed. Also, stereotypes can get richer in detail as different functions are approached.
In the classical approach to software development, you frequently find two separate phases: analysis and design. It is often said that the former deals with what the system has to do and what its structural features are, whereas the latter deals with how that functionality and structure can be effectively implemented. However, we think that the whole development lifecycle must have a greater internal homogeneity, so a modeling function can be defined and used instead. Modeling is a kind of activity during which models built in terms of some stereotypes are expressed in terms of some others. For example, user needs, expressed in terms of the requirement stereotype, can serve to create an interface model in terms of service, state, and user-interface element stereotypes during the project's definition stage.
Developers engaged in modeling often use both analytical and compositive mental resources to build models. Analytical resources allow us to decompose a structure or function into smaller (and often simpler) parts so we can better understand the whole. Compositive resources allow us to create synthetic results using smaller parts as a starting point. Different kinds of models require different amounts and proportions of analysis and composition, but the coexistence of both types of skills are key for coherent and complete models.
We discard the concepts of analysis and design as major guidelines of our methodology because analysis is just a kind of approach to modeling, and design is a synonym for modeling. In fact, models are not hidden truths waiting to be unveiled by the developer, but designed or created as one possibility out of many.
An evolutive (sometimes called "evolutionary") lifecycle lets developers build the system incrementally, adding more and more functionality as time goes on. At the end of each iteration, the system must be correct and deliverable, although not having its full functionality available. This is useful for the product's users, as they can evaluate and test the system before the development finishes, and feedback evaluation results into the development process. In "Evolutionary Fusion: A Customer-Oriented Incremental Life Cycle for Fusion" (Chapter 6 of Object-Oriented Development at Work: Fusion in the Real World, edited by R. Malan, et al., Prentice Hall, 1996), T. Cotton gives an excellent description of the key issues of this approach.
Metis has been built around an evolutive lifecycle by distinguishing a definition stage and a construction stage. During the definition stage, the system is defined in terms of its classes and services, and this is usually done as a single-pass sequence of tasks. The construction stage, on the other hand, is often performed as a set of different development cycles, all of them equal in structure but approaching different clusters of functionality. At the end of each development cycle, the system must be delivered to the users, evaluated by them, and the results of this task injected back into the development process. Furthermore, it is not necessary for the different development cycles to form a sequence, but they can be distributed as several concurrent threads of work within the organization, taking into account the appropriate dependency restrictions that may arise. This allows the independent assignment of resources to each thread or cycle as well as a very flexible development scheme that can be rearranged as necessary.
In addition, different structural or functional clusters may emerge during the definition stage, presenting each a specific set of needs. Each of these clusters can be considered a subsystem, and assigned a new full lifecycle (a subproject), starting with a requirements gathering phase from the mentioned needs. A subsystem is, in fact, another system, and is treated as such at all levels. Results integration among different subsystems and dependency management is more an organizational issue and falls beyond the scope of this article.
It is difficult, infrequent, but essentially important for a methodology to adequately support low-level development tasks. During detailed modeling inside each development cycle, more detail is given to already-used stereotypes and new ones appear. In the first group we can find the collection and relationship stereotypes; and thread, process, and component illustrate the second group. We must precisely define these stereotypes in order to use them as conceptual tools and ease the design-to-code work.
An interesting issue is that of relationships. At a detailed level, relationships between classes can be expressed as references from one another (the classical way), or else as first-level entities. Some criteria for this decision must be given, and we think that the reference concept introduced by the Fusion method in the context of visibility graphs can be helpful.
On the other hand, collections are widely used during modeling to express groups of related objects that can be accessed as a whole. Collections may be implemented as custom collection classes, generic containers taken from libraries, or plain pointers or arrays. Also, different semantics may be needed by each case, thus arising the need of considering sets, bags, sequences, and the like.
Although Metis does not impose a fixed sequence of activities, it is useful to depict a general procedure in order to better understand functions and their dependencies. Figure 1 is a diagram of a typical Metis project, including both a definition and a construction stage, and indicating how subsystems can be arranged as subprojects within Metis.
Metis is still in its infancy, but all of us at Neco walk the Metis way. This means that Metis gives support for the daily development work, which serves both as wind tunnel and as main source of practical ideas. When Metis reaches its maturity, we will consider developing a CASE tool, which will cover a usually forgotten area regarding software-development methodologies: Without a CASE tool, a number of very laborious tasks (such as crosschecking and looking for typical errors) are impractical.
DDJ