Effective Analysis for Object-Oriented Development

. We are in the business of creating and selling software. This has proven to be a surprisingly difficult task and we often fail at it. Many software projects are never completed and of those that are, many are never actually used. Why do so many of us fail to create the powerful, compelling software that we envision?

One of the main reasons we fail is that we don't articulate our vision effectively. We may fail to adequately understand the needs of our intended audience, or we may fail to quantify those needs and later measure our progress based on how well we've satisfied them. As a result our projects lose focus: We add features that aren't needed, we skip some that are needed, and we argue over priorities. We waste our resources and end up with a disappointing product that is overdue, over budget or worse, canceled altogether.

We can avoid these problems by employing the process of analysis before and during our development efforts. Simply stated, analysis is the process of providing a shared vision of what the system must do. Having a vision enables us to direct our efforts. In some ways we always do analysis at some level because we always have some intent when we sit down to write software. Having a shared vision ensures that all of the stakeholders in a project can work together. The models produced during analysis give the various stakeholders in the project the information they need in order to resolve the conflicts that will inevitably arise between them, as well as a medium for recording and modifying the resolutions to those conflicts.

There are three models that we will present: the domain model, the use-case model, and the logical architecture. We will start with a domain model that will define the objects, relationships and behaviors that already exist in the environment in which the system will be deployed. We will use the vocabulary we develop in the domain model to describe the responsibilities of the system itself and the mechanisms by which they will be discharged in the use-case model. Finally, we will complete our knowledge of the user's expectations, and validate the completeness and consistency of our earlier models by constructing a logical architecture that represents the way in which the system will appear to function.

In order to understand our motivation for building the various models, and to allow us to measure the usefulness of a given model in a particular project, we will begin with an examination of the project stakeholders and the demands they place on the analysis process.

PRIMARY STAKEHOLDERS Analysis is not a process with intrinsic value: In order to be worthwhile it must meet the needs of the project's stakeholders. It must, in fact, meet the needs of all the stakeholders or it isn't worth doing at all. We will define our criteria for successful analysis as follows: Analysis succeeds when all the stakeholders in a project share a vision of the project and use that vision to guide its development. Clearly the stakeholders will not be able to use analysis as a guide unless it meets their needs. There are four different groups of stakeholders, each of which has a different set of needs.

The customer, the end user, and the domain expert each have a unique perspective on the required behavior of the product and a personal stake in communicating it to the development team. The customer is simply whoever commissioned the project. The end user will actually use the product, and the domain expert is an expert in the field for which the product is being developed. Often, one or more of these roles will be played by the same person. Later we will see how to capture the information that we solicit from these people in our domain models.

The customer needs to know whether it makes sense to build the system. They will collaborate with a domain expert to meet this challenge along with a feasibility expert who is knowledgeable about the technologies that will be used to implement the system. The analysis models must contain enough information for these people to determine both that building the system makes sense and that it can be done with the resources that are available.

The designers of the system and its developers are the most direct consumers of the analysis models because they must design and build the software the models describe. They are almost certainly unfamiliar with the problem domain and will have to make numerous decisions about the minute details of the software's behavior, guided only by the information contained in the analysis.

The testers are the final group of stakeholders. They challenge us to give them a document that allows them to ascertain whether the system works properly once it is built. This group includes the obvious software tester, as well as the developer, who must test her work as she proceeds. It also includes the customer, who might test the software for acceptability before actually paying for it, and ultimately the end user, who may simply refuse to use the software if it does not meet her needs.

THE MODELS There are a great number of diagrams that can be used for modeling. We will not present an exhaustive survey of these diagrams here. Instead we will present a sampling of the UML diagrams that are representative of the kinds typically needed for successful analysis.

Just as there are a number of diagrams that can be used for modeling, there are a number of methods that can be used to drive the process and a number of techniques that can be used to create the diagrams. We advocate letting the rest of the development process drive the analysis and instead of providing a formal process, we offer the following words of guidance:

First, pick low-hanging fruit. Document all of what you know. Don't wait until "the right time"; if you know something is true, write it down.

Second, attack the unknowns. Focus on the high-risk items early. Look for signs of uncertainty, overconfidence, or wishful thinking on the part of the stakeholders. If you don't know what it is, you need to find out. If you expect it to be easy, it won't be. And if it sounds too good to be true, it probably is.

Third, look for patterns. Keep an eye out for relationships and behaviors that are variations on the same theme. Look for shapes that recur in your diagrams and structures that are related or complimentary. These kinds of patterns, if called out, can make a project easier to describe, build and maintain. They can even lead to greater insight into the domain of the project itself.

Now, let's take a look at the models themselves.

Domain We start by modeling the domain of the system; that is, the environment into which the system will be introduced. We do this in order to discover the forces that will shape the system, the users (human and otherwise) that will interact with the system, and the constraints within which the system will have to operate. We will also construct a vocabulary that will be useful in the construction and validation of other models. To do this we will attempt to discover and record three things:
  1. the objects (including people) that already exist in the environment;
  2. the relationships between these objects; and
  3. the behavior of these objects separate from their interaction of the system.
We can use static object and class diagrams if we want to highlight what we know about the data and functionality that exist in the domain. We use CRC cards to explore the behaviors and responsibilities of the objects, state-transition diagrams (STDs) and sequence diagrams to focus on behavior, and use cases to show responsibilities and their attendant scenarios to look at functionality. One particularly useful diagram is called a "context diagram." Context diagrams focus on identifying objects (including the system itself) and their responsibilities to each other. Figure 1 shows the context of a candy machine, presented using the UML notation.

figure 1

Figure 1. Context diagram of a candy machine.

It is often useful to augment the context diagram(s) with state-transition diagrams or use cases to illustrate the behavior or functionality of the individual elements. Figure 2 is use-case diagram that shows a simple use-case architecture for our candy machine.

figure 2

Figure 2. A simple use-case architecture.

The domain model is created mainly from information gathered from the domain expert and perhaps the customer. The end user may also contribute critical details to this model. It is useful later in analysis as a source of vocabulary and candidate use cases. The logical architecture is also used in conjunction with the domain model to validate the analysis as a whole and to verify the feasibility of the project. It is perhaps most useful to designers who can use it to identify the forces in the environment that may cause changes in the requirements in the future. This information is used to create designs that will flex in ways that will accommodate these changes.

Use Cases We mentioned above that writing use cases can be an effective way to document the responsibilities that mold the relationships among objects in the domain. Here we will focus on use cases as a tool for documenting the responsibilities of the system itself. While use cases are the main form of documentation for this type of model they may be augmented by other types of diagrams. Sequence diagrams and STDs are particularly useful and in some cases may replace the scenarios of a use case altogether, while use-case modeling focuses on the responsibilities of the system and the mechanisms that will be used to discharge those responsibilities. There may occasionally be some need to model the participants or data involved using an object or class diagram of some sort, but this is rare and may often be moved into the domain or logical architecture.

Typically, each use case is described in terms of the responsibility being executed, and the pre- and postconditions for the use case. For example:
  • Use case: Customer buys candy
  • Responsibilities: The candy-machine software shall enable the customer to buy candy by interacting with the candy-machine hardware; the candy machine shall allow the customer to abort the transaction; the candy machine shall not "cheat" the customer.
  • Precondition: none
  • Postcondition: either: 1) The customer has his candy and appropriate change, and the money acceptor has the money for the candy; or 2) both the customer and the candy machine have not changed state (the use case was aborted).
In addition to its definition, each use case is commonly accompanied by one or more scenarios. These scenarios indicate the ways that the system can interact with its environment in order to satisfy the use case. These scenarios are usually either text or some sort of sequence diagram. In either case, the scenario shows a series of actions that are performed by the system, and elements in the system to discharge the use case's responsibility, and convert its preconditions to its postconditions. For example, the sequence diagram in Figure 3 shows a scenario for the "customer buys candy" use case.

figure 3

Figure 3. A sequence diagram for buying candy.

For our candy machine the relationship between the customer entering keystrokes and entering money proves to be quite complex. It would take a large number of scenarios to document all the "legal" ways to do it. We can solve this problem using an STD as shown in Figure 4.

figure 4

Figure 4. A state-transition diagram.

Note that, in this case, it may be useful to organize the events into a hierarchy and present them in a class diagram.

The use-case model is the bread and butter of analysis. Any stakeholder that has any input into the system will likely contribute to this model. It is used as a mechanism to partition the development of the project into convenient units that can, in turn, be assigned priorities and be used to plan schedules. This partitioning can often also be used to group objects into packages. Developers, testers, and even the customer will all use the use-case model as the basis for their testing. Developers and testers will work together to create a test plan and unit tests based on the behavior described by the use-case scenarios, and the customer may use the most critical use cases as a criteria for acceptance testing.

Logical Architecture The domain model and external use cases define the "black box" behavior of our system. While this may be enough information to build a system that is technically correct, it often falls short of being enough to make our users happy. In order to completely satisfy our users we must not only supply the systems they require, but also the systems they expect.

To do this we use a logical architecture to document what the user believes the "internals" of the system to be. This model may capture the workings of a manual system that either could be or is being used to perform the same role as the proposed software system. It could represent an end user's conceptualization of the inner workings of an existing software. Or it could be that the customer finds she can best express her vision of the desired software in terms of an ersatz design document.

The logical architecture serves many of the same functions as the domain model and the use-case model. It identifies objects, relationships, and behaviors that are in the end-user's vocabulary, but that may be missing from the domain model. And, like use cases, it describes the behavior of the system, but it does so through example rather than enumeration. By providing these new perspectives the logical architecture allows us to validate and extend the other models.

The logical architecture can be captured using many of the same diagrams as the domain model. It is often the case, however, that we want to capture information about the system that is more abstract. For that we may use a package diagram as shown in Figure 5.

figure 5

Figure 5. A package-level class diagram.

Sometimes, we can only understand more detailed requirements by having a more detailed logical architecture. For example, in our ViewGraph package there are logical business objects such as documents, drawing shapes, drawing tools, and so on. These things are known to exist, even if we don't know their exact form. By working with our end user we may develop a more detailed view of portions of the logical architecture, such as the class diagram in Figure 6 that shows the apparent relationships between some of the drawing elements and tools.

figure 6

Figure 6. A class model.

Like the domain model, the logical architecture may be used to capture behaviors, as well as objects and relationships. One useful way to do this is to borrow scenarios from use cases. These scenarios, also called user stories, differ from full use cases in that they focus on behavior rather than responsibilities, and they make no formal distinction between actors and the system—these stories represent an interaction rather than a transaction. These speculative narratives are useful because they can shed light on assumed requirements that might otherwise have been missed. They are also a useful source of domain vocabulary. Sometimes it is useful to have a more formal representation of these stories as demonstrated in the sequence diagram in Figure 7.

figure 7

Figure 7. The move_shapes sequence diagram for the ViewGraph package.

This sequence diagram shows the interactions that take place when the MoveShapesTool's responsibility to move_shapes is carried out. This sequence diagram shows how the logical entities cause each other's responsibilities to be carried out in order to accomplish another (higher level) responsibility. Similarly, the sequence diagram in Figure 8 illustrates the logical interactions that take place when ChangeColorTool's responsibility to change_shapes is carried out.

figure 8

Figure 8. The change_shapes_color sequence diagram for the ViewGraph package.

Earlier we advised that the discovery and documentation of patterns was an important part of analysis. Here we have an opportunity to demonstrate what we meant by that advice. First we notice that the sequence diagrams in Figures 7 and 8 are visibly similar, and upon further examination we discover that all of their elements are either conceptually or physically the same. We can capture the relationship between these diagrams in an abstract sequence diagram as shown in Figure 9.

figure 9

Figure 9. An abstract interaction diagram.

As noted earlier a logical architecture can serve as a tool for validating and extending the other analytic models. It can also be used to gain insights into ways to partition the other analytic models and is invaluable when used in conjunction with the domain model for determining the feasibility of the project. During design the logical architecture can be used as a straw man for the real architecture and perhaps the physical deployment of the product as well. Like the domain model, it is also a valuable source of information about the forces that may ultimately cause the requirements of the project to change.

CONCLUSION We have just seen an overview of three major models used for the analysis of software projects. These models exist to aid in the determination of the project's feasibility and later to support its design and testing. As such they may be revisited, updated and even completely overhauled at any time during the development process as dictated by the needs of the project's stakeholders.

As a software project ages, the analytic models become its chronicle, passing the insights of the original engineering team down to those that must maintain, extend and document the system. With the domain model providing a context for understanding the system, the use-case model demonstrating its use, and the logical architecture lending a metaphorical glimpse into its inner workings; the artifacts of analysis combine to give long life to a shared vision.

Suggested Reading

  1. Rational Software. Unified Modeling Language, version 1.1, 1997.
  2. Firesmith, D., B. Henderson-Sellers, and I. Graham. OPEN Modeling Language, SIGS Books, New York, 1997.
  3. Jacobson, I. et al. Object-Oriented Software Engineering: A Use Case Driven Approach, Addison-Wesley, New York, 1992.
  4. Booch, G. Object-Oriented Analysis and Design with Applications, Benjamin Cummings, Redwood City, CA, 1994.
  5. Rumbaugh, J. et al. Object-Oriented Modeling and Design, Prentice Hall, Englewood Cliffs, NJ, 1991.
  6. Coleman, D. et al. Object-Oriented Development: The Fusion Method, Prentice Hall, Englewood Cliffs, NJ, 1994.
  7. Coad, P. and E. Yourdon. Object-Oriented Analysis, Yourdon Press, 1990.
  8. Wirfs-Brock, R., B. Wilkerson, and L. Wiener. Designing Object-Oriented Software, Prentice Hall, Englewood Cliffs, NJ, 1990.
  9. Rawsthorne, D. "Requirements Modeling," Chapter in Handbook of Object Technology, to be published by CRC Press in late 1998.

Dan Rawsthorne is the Director of Program Management and Process Development at Access, a Seattle-based company. He can be contacted at [email protected]. Phil Goodwin is a Senior Software Engineer at Camstar Systems Inc. in Campbell, CA. He can be contacted at [email protected].