Common Modeling Techniques
Modeling Source Code
If you develop software in Java, you'll usually save your source code in .java files. If you develop software using C++, you'll typically store your source code in header files (.h files) and bodies (.cpp files). If you use IDL to develop COM+ or CORBA applications, one interface from your design view will often expand into four source code files: the interface itself, the client proxy, the server stub, and a bridge class. As your application grows, no matter which language you use, you'll find yourself organizing these files into larger groups. Furthermore, during the construction phase of development, you'll probably end up creating new versions of some of these files for each new incremental release you produce, and you'll want to place these versions under the control of a configuration management system.Much of the time, you will not need to model this aspect of a system directly. Instead, you'll let your development environment keep track of these files and their relationships. Sometimes, however, it's helpful to visualize these source code files and their relationships using artifact diagrams. Artifact diagrams used in this way typically contain only work-product artifacts stereotyped as files, together with dependency relationships. For example, you might reverse engineer a set of source code files to visualize their web of compilation dependencies. You can go in the other direction by specifying the relationships among your source code files and then using those models as input to compilation tools, such as make on Unix. Similarly, you might want to use artifact diagrams to visualize the history of a set of source code files that are under configuration management. By extracting information from your configuration management system, such as the number of times a source code file has been checked out over a period of time, you can use that information to color artifact diagrams, showing "hot spots" of change among your source code files and areas of architectural churn.
The file stereotype for artifacts is discussed in Chapter 26 . |
- Either by forward or reverse engineering, identify the set of source code files of interest and model them as artifacts stereotyped as files.
- For larger systems, use packages to show groups of source code files.
- Consider exposing a tagged value indicating such information as the version number of the source code file, its author, and the date it was last changed. Use tools to manage the value of this tag.
- Model the compilation dependencies among the source files using dependencies. Again, use tools to help generate and manage these dependencies.
For example, Figure 30-2 shows five source code files. The file signal.h is a header file. Three of its versions are shown, tracing from new versions back to their older ancestors. Each variant of this source code file is rendered with a tagged value exposing its version number.
Figure 30-2. Modeling Source Code

The trace dependency stereotype is discussed in Chapter 10 . |
Modeling an Executable Release
Releasing a simple application is easy: You throw the bits of a single executable file on a disk and your users just run that executable. For these kinds of applications, you don't need artifact diagrams because there's nothing difficult to visualize, specify, construct, or document.Releasing anything other than a simple application is not so easy. You need the main executable (usually, a .exe file), but you also need all its ancillary parts, such as libraries (commonly .dll files if you are working in the context of COM+, or .class and .jar files if you are working in the context of Java), databases, help files, and resource files. For distributed systems, you'll likely have multiple executables and other parts scattered across various nodes. If you are working with a system of applications, you'll find that some of these artifacts are unique to each application but that many are shared among applications. As you evolve your system, controlling the configuration of these many artifacts becomes an important activityand a more difficult one because changes in the artifacts associated with one application may affect the operation of other applications.For this reason, you use artifact diagrams to visualize, specify, construct, and document the configuration of your executable releases, encompassing the deployment artifacts that form each release and the relationships among those artifacts. You can use artifact diagrams to forward engineer a new system and to reverse engineer an existing one.When you create artifact diagrams such as these, you actually just model a part of the things and relationships that make up your system's implementation view. For this reason, each artifact diagram should focus on one set of artifacts at a time.To model an executable release,
- Identify the set of artifacts you'd like to model. Typically, this will involve some or all the artifacts that live on one node, or the distribution of these sets of artifacts across all the nodes in the system.
The UML's extensibility mechanisms are discussed in Chapter 6; interfaces are discussed in Chapter 11 . - Consider the stereotype of each artifact in this set. For most systems, you'll find a small number of different kinds of artifacts (such as executables, libraries, tables, files, and documents). You can use the UML's extensibility mechanisms to provide visual cues for these stereotypes.
- For each artifact in this set, consider its relationship to its neighbors. Most often, this will involve interfaces that are exported (realized) by certain artifacts and then imported (used) by others. If you want to expose the seams in your system, model these interfaces explicitly. If you want your model at a higher level of abstraction, elide these relationships by showing only dependencies among the artifacts.
For example, Figure 30-3 models part of the executable release for an autonomous robot. This figure focuses on the deployment artifacts associated with the robot's driving and calculation functions. You'll find one artifact (driver.dll) that manifests a component Driving that exports an interface (IDrive) that is, in turn, used by another component Path manifested by another artifact (path.dll). The dependency among components Path and Driving induces a dependency among the artifacts path.dll and driver.dll that implement them. There's one other artifact shown in this diagram (collision.dll), and it, too, manifests a component, although these details are elided: path.dll is shown with a dependency directly to collision.dll.
Figure 30-3. Modeling an Executable Release

Modeling a Physical Database
A logical database schema captures the vocabulary of a system's persistent data, along with the semantics of their relationships. Physically, these things are stored in a database for later retrieval, either a relational database, an object-oriented one, or a hybrid object/relational database. The UML is well suited to modeling physical databases as well as logical database schemas.
Modeling a logical database schema is discussed in Chapter 8 . |
Physical database design is beyond the scope of this book; the focus here is simply to show you how you can model databases and tables using the UML . |
- (Push down)
Define a separate table for each class. This is a simple but naive approach because it introduces maintenance headaches when you add new child classes or modify your parent classes. - (Pull up)
Collapse your inheritance lattices so that all instances of any class in a hierarchy has the same state. The downside with this approach is that you end up storing superfluous information for many instances. - (Split tables)
Separate parent and child states into different tables. This approach best mirrors your inheritance lattice, but the downside is that traversing your data will require many cross-table joins.
- For simple CRUD (create, read, update, delete) operations, implement them with standard SQL or ODBC calls.
- For more-complex behavior (such as business rules), map them to triggers or stored procedures.
- Identify the classes in your model that represent your logical database schema.
- Select a strategy for mapping these classes to tables. You will also want to consider the physical distribution of your databases. Your mapping strategy will be affected by the location in which you want your data to live on your deployed system.
- To visualize, specify, construct, and document your mapping, create an artifact diagram that contains artifacts stereotyped as tables.
- Where possible, use tools to help you transform your logical design into a physical design.
Figure 30-4 shows a set of database tables drawn from an information system for a school. You will find one database (school.db with the stereotypdatabase) that's composed of five tables: student, class, instructor, department, and course. In the corresponding logical database schema, there was no inheritance, so mapping to this physical database design is straightforward.
Figure 30-4. Modeling a Physical Database

Modeling Adaptable Systems
All the artifact diagrams shown thus far have been used to model static views. Their artifacts spend their entire lives on one node. This is the most common situation you'll encounter, but especially in the domain of complex, distributed systems, you'll need to model dynamic views. For example, you might have a system that replicates its databases across several nodes, switching the one that is the primary database when a server goes down. Similarly, if you are modeling a globally distributed 24x7 operation (that is, a system that's up 24 hours a day, 7 days a week), you will likely encounter mobile agents, artifacts that migrate from node to node to carry out some transaction. To model these dynamic views, you'll need to use a combination of artifact diagrams, object diagrams, and interaction diagrams.To model an adaptable system,
- Consider the physical distribution of the artifacts that may migrate from node to node. You can specify the location of an artifact instance by marking it with a location attribute, which you can then render in an artifact diagram.
The location attribute is discussed in Chapter 24; object diagrams are discussed in Chapter 14 . - If you want to model the actions that cause an artifact to migrate, create a corresponding interaction diagram that contains artifact instances. You can illustrate a change of location by drawing the same instance more than once, but with different values for its state, which includes its location.
For example, Figure 30-5 models the replication of the database from the previous figure. We show two instances of the artifact school.db. Both instances are anonymous, and both have a different value for their location tagged value. There's also a note, which explicitly specifies which instance replicates the other.
Figure 30-5. Modeling Adaptable Systems

Interaction diagrams are discussed in Chapter 19 . |
Forward and Reverse Engineering
Forward engineering and reverse engineering artifacts are pretty direct, because artifacts are themselves physical things (executables, libraries, tables, files, and documents) that are therefore close to the running system. When you forward engineer a class or a collaboration, you really forward engineer to an artifact that represents the source code, binary library, or executable for that class or collaboration. Similarly, when you reverse engineer source code, binary libraries, or executables, you really reverse engineer to an artifact or set of artifacts that, in turn, trace to classes or collaborations.Choosing to forward engineer (the creation of code from a model) a class or collaboration to source code, a binary library, or an executable is a mapping decision you have to make. You'll want to take your logical models to source code if you are interested in controlling the configuration management of files that are then manipulated by a development environment. You'll want to take your logical models directly to binary libraries or executables if you are interested in managing the artifacts that you'll actually deploy on a running system. In some cases, you'll want to do both. A class or collaboration may be manifested by source code as well as by a binary library or executable.To forward engineer an artifact diagram,
- For each artifact, identify the classes or collaborations that the artifact implements. Show this with a manifest relationship.
- Choose the form for each artifact. Your choice is basically between source code (a form that can be manipulated by development tools) or a binary library or executable (a form that can be dropped into a running system).
- Use tools to forward engineer your models.
Reverse engineering (the creation of a model from code) an artifact diagram is straightforward, but obtaining a class model is not a perfect process because there is always a loss of information. From source code, you can reverse engineer back to classes; this is the most common thing you'll do. Reverse engineering source code to artifacts will uncover compilation dependencies among those files. For binary libraries, the best you can hope for is to denote the library as an artifact and then discover its interfaces by reverse engineering. This is the second most common thing you'll do with artifact diagrams. In fact, this is a useful way to approach a set of new libraries that may be otherwise poorly documented. For executables, the best you can hope for is to denote the executable as an artifact and then disassemble its codesomething you'll rarely need to do unless you work in assembly language.
Reverse engineering class diagrams is discussed in Chapter 8 . |
- Choose the target you want to reverse engineer. Source code can be reverse engineered to discover artifacts and then classes. Binary libraries can be reverse engineered to uncover their interfaces. Executables can be reverse engineered the least.
- Using a tool, point to the code you'd like to reverse engineer. Use your tool to generate a new model or to modify an existing one that was previously forward engineered.
- Using your tool, create an artifact diagram by querying the model. For example, you might start with one or more artifacts, then expand the diagram by following relationships or neighboring artifacts. Expose or hide the details of the contents of this artifact diagram as necessary to communicate your intent.
For example, Figure 30-6 provides an artifact diagram that represents the reverse engineering of the ActiveX artifact vbrun.dll. As the figure shows, the artifact manifests 11 interfaces. Given this diagram, you can begin to understand the semantics of the artifact by next exploring the details of its interface classes.