Common Modeling Techniques
Modeling Simple Collaborations
No class stands alone. Rather, each works in collaboration with others to carry out some semantics greater than each individual. Therefore, in addition to capturing the vocabulary of your system, you'll also need to turn your attention to visualizing, specifying, constructing, and documenting the various ways these things in your vocabulary work together. You use class diagrams to represent such collaborations.To model a collaboration,
- Identify the mechanism you'd like to model. A mechanism represents some function or behavior of the part of the system you are modeling that results from the interaction of a society of classes, interfaces, and other things.
- For each mechanism, identify the classes, interfaces, and other collaborations that participate in this collaboration. Identify the relationships among these things as well.
- Use scenarios to walk through these things. Along the way, you'll discover parts of your model that were missing and parts that were just plain semantically wrong.
- Be sure to populate these elements with their contents. For classes, start with getting a good balance of responsibilities. Then, over time, turn these into concrete attributes and operations.
Mechanisms such as this are often coupled to use cases, as discussed in Chapter 17; scenarios are threads through a use case, as discussed in Chapter 16 . |
Figure 8-2. Modeling Simple Collaborations

Modeling a Logical Database Schema
Many of the systems you'll model will have persistent objects, which means that they can be stored in a database for later retrieval. Most often, you'll use a relational database, an object-oriented database, or a hybrid object/relational database for persistent storage. The UML is well-suited to modeling logical database schemas, as well as physical databases themselves.
Modeling the distribution and of objects is discussed in Chapter 24; modeling physical databases is discussed in Chapter 30 . |
- Identify those classes in your model whose state must transcend the lifetime of their applications.
- Create a class diagram that contains these classes. You can define your own set of stereotypes and tagged values to address database-specific details.
Stereotypes are discussed in Chapter 6 . - Expand the structural details of these classes. In general, this means specifying the details of their attributes and focusing on the associations and their multiplicities that relate these classes.
- Watch for common patterns that complicate physical database design, such as cyclic associations and one-to-one associations. Where necessary, create intermediate abstractions to simplify your logical structure.
- Consider also the behavior of these classes by expanding operations that are important for data access and data integrity. In general, to provide a better separation of concerns, business rules concerned with the manipulation of sets of these objects should be encapsulated in a layer above these persistent classes.
- Where possible, use tools to help you transform your logical design into a physical design.
NoteLogical database design is beyond the scope of this book. The focus here is simply to show how you can model schemas using the UML. In practice, you'll end up using stereotypes tuned to the kind of database (relational or object-oriented) you are using.Figure 8-3 shows a set of classes drawn from an information system for a school. This figure expands upon an earlier class diagram, and you'll see the details of these classes revealed to a level sufficient to construct a physical database. Starting at the bottom-left of this diagram, you will find the classes named Student, Course, and Instructor. There's an association between Student and Course, specifying that students attend courses. Furthermore, every student may attend any number of courses, and every course may have any number of students.
Figure 8-3. Modeling a Schema

Modeling primitive types is discussed in Chapter 4; aggregation is discussed in Chapters 5 and 10 . |
Forward and Reverse Engineering
Modeling is important, but you have to remember that the primary product of a development team is software, not diagrams. Of course, the reason for creating models is to be able to deliver software that satisfies the evolving goals of its users and the business at the right time. For this reason, it's important that the models you create and the implementations you deploy map to one another and do so in a way that minimizes or even eliminates the cost of keeping your models and your implementation in sync with one another.
The importance of modeling is discussed in Chapter 1 . |
Activity diagrams are discussed in Chapter 20 . |
Stereotypes and tagged values are discussed in Chapter 6 . |
- Identify the rules for mapping to your implementation language or languages of choice. This is something you'll want to do for your project or your organization as a whole.
- Depending on the semantics of the languages you choose, you may want to constrain your use of certain UML features. For example, the UML permits you to model multiple inheritance, but Smalltalk permits only single inheritance. You can choose to prohibit developers from modeling with multiple inheritance (which makes your models language-dependent), or you can develop idioms that transform these richer features into the implementation language (which makes the mapping more complex).
- Use tagged values to guide implementation choices in your target language. You can do this at the level of individual classes if you need precise control. You can also do so at a higher level, such as with collaborations or packages.
- Use tools to generate code.
Figure 8-4 illustrates a simple class diagram specifying an instantiation of the chain of responsibility pattern. This particular instantiation involves three classes: Client, EventHandler, and GUIEventHandler. The classes Client and EventHandler are abstract, whereas GUIEventHandler is concrete. EventHandler has the usual operation expected of this pattern (handleRequest), although two private attributes have been added for this instantiation.
Figure 8-4. Forward Engineering

Patterns are discussed in Chapter 29 . |
Reverse engineering is the process of transforming code into a model through a mapping from a specific implementation language. Reverse engineering results in a flood of information, some of which is at a lower level of detail than you'll need to build useful models. At the same time, reverse engineering is incomplete. There is a loss of information when forward engineering models into code, and so you can't completely recreate a model from code unless your tools encode information in the source comments that goes beyond the semantics of the implementation language.To reverse engineer a class diagram,
public abstract class EventHandler {
EventHandler successor;
private Integer currentEventID;
private String source;
EventHandler() {}
public void handleRequest() {}
}
- Identify the rules for mapping from your implementation language or languages of choice. This is something you'll want to do for your project or your organization as a whole.
- Using a tool, point to the code you'd like to reverse engineer. Use your tool to generate a new model or modify an existing one that was previously forward engineered. It is unreasonable to expect to reverse engineer a single concise model from a large body of code. You need to select portion of the code and build the model from the bottom.
- Using your tool, create a class diagram by querying the model. For example, you might start with one or more classes, then expand the diagram by following specific relationships or other neighboring classes. Expose or hide details of the contents of this class diagram as necessary to communicate your intent.
- Manually add design information to the model to express the intent of the design that is missing or hidden in the code.