Not surprisingly, traces and static models document the behavior of elements in a system to different extents. In the documentation of a static behavioral model of a particular element, you typically find all the resources identified in the interfaces of that element: the complete behavior of the element. In the documentation of a trace, however, you find only the resources identified in the element interfaces that are involved in the execution of that particular scenario.
Another difference between the two approaches is the focus of the documentation relative to individual elements. Traces are typically scoped to include all the system elements that are involved in a particular scenario. However, as mentioned earlier, only a fraction of the behavior of any given element shows up in any particular trace. Each static model, on the other hand, is typically scoped to focus on all the behavior of a particular element. In order to reason about
systemwide
behavior, you must look at multiple static models side by side.
Many languages and notations are available for both types of behavioral documentation. These
differ
in the emphasis that is put on certain aspects of the behavior, such as how ordering is identified, how much support is available for documenting timing, what types of communication are easily
modeled
, and so on.
In the sections that follow, we provide cursory overviews of several notations within each of these categories. The discussions are intended to provide a flavor of the particular notations and to motivate their use. There are many ways in which the diagrams we present in this section may be used together to support the design process. Figure 8.1 shows a reasonable way to combine the strengths of several notations during the design processes.
Each of the following notation sections is presented in terms of a common example, JavaPhone, an example
meant
to facilitate the development of telecommunication-aware applications on any platform supporting the standard. The JavaPhone example documents resources available for use in telephony, data communication, power management, and many other areas. We focus on a small portion of JavaPhone: making a point-to-point connection, or placing a call.
8.5.1 Traces
Traces are sequences of activities or interactions that describe the system's response to a specific stimulus when the system is in a specific state. These sequences document the trace of activities through a system described in terms of its structural elements and their interactions. Although it is conceivable to describe all possible traces through a set of elements to generate the equivalent of a static behavioral model, it is not the
intention
of trace-oriented documentation to do so. This would reduce the benefit of being readily comprehensible, owing to the resultant loss of focus.
In this section, we describe five notations for documenting traces: use cases, use case maps, sequence diagrams, collaboration diagrams, and message sequence
charts
. Although other notations are available, we have
chosen
these five as a reasonably representative sample of various types of trace-based notations.
Use Cases
A use case is a description of a unit of functionality performed by a single element. The functionality is described by documenting the sequence of interactions in which the element engages in order to provide the functionality. All interactions in a use case are interactions between the element and actors in its environment; no interactions within the element are shown. Use cases often include variants of the main sequence of interactions in order to document exceptional conditions.
Use cases are frequently used to capture initial requirements for a system by producing a use case for each system requirement. The element in these use cases represents the system itself, and each interaction is an interaction with an actor in the system's environment.
UML does not define any set notation for documenting use cases, but notations used in practice are
generally
brief and textual. Figure 8.2 uses one such ad hoc notation used to document a use case for JavaPhone.
Use Case Maps
The use case map notation was developed at Carleton University and has been used to document and to understand a wide range of applications since 1992. Use case maps concentrate on visualizing execution paths through a set of elements from a bird's-eye view. The
fairly
intuitive notation helps communicate how a system works or is supposed to work, without getting lost in too much detail.
Use case maps can be derived from informal requirements or from use cases, if they are available. Responsibilities need to be stated or be inferred from these requirements. Separate use case maps can be created for individual system functionalities or even for individual scenarios. However, the strength of this notation resides
mainly
in the integration of
related
scenarios. In such cases, use case maps can be used to
illustrate
concurrency, such as resource
contention
problems—multiple paths using one element—or possible deadlock situations—two paths in
opposite
directions through at least two of the same elements.
If you ever followed a discussion of developers trying to answer concurrency-related questions—Does an element need to be locked? Is there potential for deadlock?—you may have seen them drawing pictures like the sketch in Figure 8.3. This type of informal notation is useful in answering such questions and illustrates a need for the
well-defined
equivalent found in use case maps.
The basic idea behind use case maps is captured by the phrase "
causal
paths cutting across organizational structures." An execution path in a use case map is just that; it describes how elements are ordered according to the responsibilities they carry out. When it enters an element, a box, an execution path, or line, states that now this element does its part to achieve the system's functionality. A responsibility that is assigned to the path while within an element defines it as a responsibility of the element.
Figure 8.4 shows an example JavaPhone use case map that deals with establishing a point-to-point connection. Use case maps include a means to represent execution path decomposition, allowing step-by-step understanding of more and more details of the system. Figure 8.4 includes an example of this. The Callee service stub, shown in the Root use case map with a diamond-shaped symbol, can be decomposed into either of the other use case maps—Callee service: Basic call or Callee service: Call forwarding. In this specific case, the decomposition is showing variation. The use case map notation includes many other symbols for such features as timers and timeouts, data containers, interactions between execution paths—aborting—and goals, which are very useful when describing
agent-oriented
elements.
Sequence Diagrams
Sequence diagrams document a sequence of interactions, presenting a collaboration in terms of instances of elements defined in the structural documentation with superimposed interactions arranged in time sequence. In particular, a sequence diagram shows only the instances participating in the scenario being documented. A sequence diagram has two dimensions: vertical, representing time, and horizontal, representing the various instances. In a sequence diagram, relationships among the objects—like those found in a module view—are not shown.
Sequence diagrams support picturing dependent interactions, showing which stimulus
follows
another stimulus. Sequence diagrams are not very explicit in showing concurrency, however. Although a sequence diagram shows instances as concurrent units, no assumptions can be made about ordering when a sequence diagram depicts an instance sending messages at the "same time" to different instances or, conversely, receiving multiple stimuli at the "same time."
It might be intended that the interactions shown in different sequence diagrams can be performed independently of one another. If this is the intention when documenting behavior using sequence diagrams, it should be noted somewhere. It is not appropriate to document independent behaviors within the same sequence diagram.
Figure 8.5 shows a very simple, UML sequence diagram.
Figure 8.6 shows a more interesting sequence diagram, one that documents a portion of our running JavaPhone example. UML's sequence chart notation supports more features than we have
illustrated
. For example, interactions can be documented using different types of arrows to indicate more specific semantics for the communication (e.g., synchronous, asynchronous, periodic, and aperiodic types of communication). There are also ways to depict forms of flow control (e.g., decisions and iteration).
A constraint language, such as UML's Object Constraint Language (OCL), can be used to add more precise definitions of conditions like guard or iteration conditions. OCL statements can be attached to the arrow and become
recurrence
values of the action attached to the stimulus. A return arrow departing the end of the focus of control maps into a stimulus that (re)activates the sender of the predecessor stimulus.
Collaboration Diagrams
Like other trace notations, a collaboration diagram shows ordered interactions among elements needed to accomplish a purpose. Whereas a sequence diagram shows order using a time-line-like mechanism, a collaboration diagram shows a graph of interacting elements and annotates each interaction with a number denoting order. Instances shown in a collaboration diagram are instances of elements described in the
accompanying
structural documentation. Collaboration diagrams are useful when the task is to verify that an architecture can fulfill the functional requirements. The diagrams are not useful if the understanding of concurrent actions is important, as when conducting a performance analysis.
A collaboration diagram also shows relationships among the elements, called links (see Figure 8.7). Links show important aspects of relationships among those structural instances. Links between the same instances in different collaboration diagrams can show different aspects of relationships between the same structural elements. Links between instances have no direction. A link simply states that the connected instances can interact. If a more accurate definition is required, additional documentation elements—perhaps textual description—have to be introduced.
Collaboration diagrams and sequence diagrams express similar information. Sequence diagrams show time sequences explicitly, making it easy to see the order in which interactions occur; collaboration diagrams indicate ordering by using numbers. Collaboration diagrams show element relationships, making it easy to see how elements are statically connected; sequence diagrams do not show these relations if connected elements do not interact in the scenario depicted in the sequence diagram.
Message Sequence Charts
A message sequence chart is a message-oriented representation containing the description of the asynchronous communication between instances. Simple message sequence charts look like sequence diagrams, but have a more specific definition and have a richer notation. The main area of application for a message sequence chart is as an overview specification of the communication behavior among interacting systems,
especially
telecommunication switching systems.
Message sequence charts may be used for requirement specification, simulation and validation, test-case specification, and system documentation. They allow documentation of traces through the system in the form of a message flow. A big advantage of a message sequence chart is that it defines a textual notation in addition to its graphical notation. This allows a more
formalized
model that can generate test cases that test an implementation against its specification.
Message sequence charts are often seen in conjunction with specification and description language (SDL), discussed later in this chapter. Whereas a message sequence chart focuses on representing the message exchange
between
elements, such as systems and processes, SDL focuses on documenting what does or should happen
in
an element. In that respect, message sequence charts and SDL diagrams complement each other.
Although message sequence charts look similar to sequence diagrams, they are used for different purposes. A sequence diagram is systemcentric in that it is used to track a scenario through the system, showing which elements are involved and how. A message sequence chart is elementcentric, and focuses on one element and how it
interacts
with its environment, without regard to the identity of other elements.
The most fundamental language constructs of message sequence charts are instances, or elements, and messages describing communication events, or interactions. Figure 8.8 shows how the JavaPhone layer interacts with its environment in establishing a point-to-point connection. In a message sequence chart, communication with outside elements is shown by message flow from and to the frame that marks the system environment. Figure 8.8 also documents actions—Alert and Establish Connection—and the setting and resetting of a timer.
The complete message sequence chart language has many other primitives, such as for local actions, timers—set, reset, and timeout—process creation, and process stop. Furthermore, message sequence charts have a means to show decomposition and so can be used to construct modular specifications.
8.5.2 Static Models
Static models show the complete behavior of structural elements. Given this type of documentation, it is possible to infer all possible traces through a system. The state machine formalism is a good candidate for representing the behavior of architectural elements because each state is an abstraction of all possible histories that could lead to that state. Once a system is in a state, it doesn't matter how it got there, only that it is there; it will
react
to the occurrence of a given event in the same way, no matter the particular history of the system at the time the event occurs. Languages are available that allow you to also document the internal behavior of elements in terms of finite state machines and element-to-element interactions in terms of interprocess communication of various types. These languages allow you to overlay a structural description of the elements of the system with constraints on interactions and timed
reactions
to both internal and environmental stimuli.
In this section, we describe three state-based languages: statecharts, specification and description language (SDL), and Z. Although other languages are available, we have chosen these three because they allow you to describe the basic concepts of documenting behavior in forms that capture the essence of what you wish to
convey
to system stakeholders. The three are also used as base representations in tools that you are most likely to encounter. Each language has been incorporated into one or more development environments that allow you to design, simulate, and analyze your system early in the development process.
Statecharts
Statecharts, a graphical formalism developed by David Harel for modeling reactive systems, allow you to trace the behavior of your system, given specific inputs. Statecharts add a number of useful extensions to traditional state diagrams, such as the nesting of states, concurrency, and primitives to express communication among concurrent units. These extensions provide the expressive power to document behavior concisely and to effectively model abstraction and concurrency.
Statecharts extend the finite state machine formalism to support description of the transitions within a state in terms of nested states. The outer state is called the
superstate;
inner states,
substates
.
The superstate defines the scope of a new statechart, and the substates are related by transitions, just as in a finite state machine. When the superstate is entered, the initial state within the superstate is also entered. Grouping substates into a superstate is often done to allow common behavior to be expressed concisely. Any behavior indicated at the superstate level—depicted as transitions from the superstate boundary rather than from any specific substate—applies to all substates. A good use of this technique is to indicate common error handling or termination behavior. Figure 8.9 shows an example of this; the alerting, failed, and connected states within the Connection state are grouped into an unnamed superstate so that common disconnection behavior can be
expressed
.
States can be nested in a different way to express concurrency. If the substates are separated by a concurrency boundary—a dotted line—rather than by transitions, each substate is also entered whenever the superstate is entered. Typically, this form of nesting is combined with the first. For example, a top-level superstate is
composed
of two or more concurrent substates. Each of the concurrent substates is in
turn
a superstate to substates that are connected by transitions.
This is, in fact, exactly the pattern followed in Figure 8.9. The top-level superstate, JTAPI, is composed of the three concurrent substates Call, Connection, and Terminal Connection. Each of these three substates is in turn a superstate to
numerous
other states, such as idle, active, and inactive in the Call state, connected by transitions. In Figure 8.9, the default start for each substate is depicted by an arrow coming from the initial state: a solid black circle. Initially, Call is in the idle state. As soon as the connect event arrives, Call generates a create event for Connection: the Connection.create action, which transitions Connection into the idle state. From there, events are exchanged with the telecommunication platform, and a Terminal Connection is created. Terminal Connection receives events from the telecommunication platform, which lead to state changes. Those changes trigger state changes in Connection, which trigger state changes in Call. Ultimately, each concurrent state transitions to the end state, a solid black circle
enclosed
by another circle; for example, on reaching the inactive state, Call transitions to the end state.
With the introduction of concurrency to finite state machines came a need to express communication among states. For example, when an event generated in one concurrent substate is intended to cause a transition in another substate, it is useful to indicate which substate should
consume
the event. For example, in Figure 8.9, a create event within the Call state is generated and intended to be consumed by the Connection state; this is denoted by labeling the event as Connection. create. This type of communication among statecharts is also needed when documenting interactions between statechart models for different elements of a system.
The statechart in Figure 8.9 shows the states some of the JavaPhone objects—Call, Connection, and Terminal Connection—can be in when a phone connection is established and disconnected. The statechart shown contains important states and transitions but is by no means complete.
Statechart notation contains many other features not mentioned here, such as means of
expressing
choice, timing, and history and has been incorporated in UML.
SDL
Specification and description language (SDL) is an object-oriented formal language defined by the International Telecommunications Union (ITU)-Telecommunications Standardization Sector. The language is intended for the documentation of complex, event-driven, real-time, and interactive applications involving many concurrent elements that communicate by using discrete signals. The most common application is in the telephony area.
SDL is an accessible language that can be used in an environment that is
constructed
of tools that support documentation, analysis, and generation of systems. SDL's strength lies in describing what happens within a system. If the focus is on interaction between systems, then a message-oriented representation, such as message sequence charts, is more suitable. SDL specifications are often used in combination with message sequence charts to explore a system's behavior.
SDL uses a finite state machine formalism at its
core
to model behavior. Constructs for describing hierarchical structure and interelement behavior enhance the capability for modeling large-scale systems. Structure is described in terms of a hierarchy of blocks that are eventually refined into sets of processes, as shown in Figure 8.10. Flow of data and stimulation among blocks and processes are described as signals that travel over named channels.
Signals
are the means of communication between blocks and processes. Communication is asynchronous and is specified textually as an annotation attached to a communication channel. Signals are visible to other blocks/processes at lower levels in the hierarchy, not to enclose blocks or other blocks at the same level.
Processes run concurrently and have no knowledge of one another's states. Processes can be
instantiated
at startup or while the system is running. The internal behavior of a process is documented using a finite state machine formalism resembling flowchart notation. SDL provides a rich set of flowchart symbols, some of which are used in Figure 8.11 to partially document how a Terminal Connection is
formed
.
SDL supports
user
-defined data types and provides several predefined types—Integer, Real, Natural, Boolean, Character, Charstring, PId, Duration, and Time—that have expected meanings.
Variables
, user-defined data types, and constant data values can be declared.
The hierarchy of blocks provides a structural view of the system; the flow among the blocks and processes, combined with process flowcharts, document system behavior. Once these aspects have been documented, it is possible to simulate the system and to observe control and data flow through the system as signals pass from block to block and into processes, where they move through the flowchart model of process behavior. This type of simulation allows you to visibly check how your system will react to various stimuli.
Z
Z, pronounced "
zed,
" is a mathematical language based on predicate logic and set theory. As a language for formal specification, Z is used to produce precise behavioral models and
permits
rigorous
analyses, such as type checking, model checking, and proofs. Z models document what behavior a system must exhibit, without constraining how it must be implemented. Z does so by focusing on data and operations involving the data.
Systems are specified as collections of
schemas
. Each schema documents a portion of the system; the two basic types of schema are often referred to as state schema and operation schema. A state schema contains a set of variables and invariants over those variables, the
allowable
combinations of which are permissible states of the system. An operation schema documents an operation over the state schema, documenting when it is allowed, via preconditions, and what is true when it is completed, via state changes. A simple banking example illustrating these schema types is shown in Figure 8.12.
Schemas allow the designer and other users of the specification to focus on one aspect of the system at a time and can also be combined using schema calculus to create complete behavioral models. The language supports a compositional approach to development, providing increased tractability when documenting large systems.
For example, Figure 8.12 could easily be extended using Z's schema calculus to deal with different aspects of a withdrawal. An additional operation schema could be written that focuses only on PIN verification at an ATM, and this operation could be combined with the Withdraw operation to express more complex behavior.
Figure 8.13 shows how we might document the running JavaPhone example in Z. However, we have restricted the example to the type of information conveyed in the other languages in this chapter, and so the figure doesn't contain the same kind of detail as in Figure 8.12. Essentially, Figure 8.13 uses the Z language to document when interactions are al-lowed but on a per interaction basis.
We've provided only a flavor of Z. Many other constructs are available for specifying more complex data types and relationships. Description of the schema calculus is beyond the scope of this presentation, as are the details of Z type checking and proof techniques. Additionally, a number of extensions to the Z notation, like Object Z and TCOZ, deal with such concepts as object orientation.
Z is particularly useful when you want to
prove
correct behavior in all cases, as when developing safety-critical systems. Additionally, commercial tools are available supporting development based on Z. Many
practitioners
who are
experienced
in the use of the language consider Z an invaluable tool because of these strengths. However, the language Z includes a large set of symbols, and expressions are written in terms of predicate logic, making it difficult for some designers to warm up to.
Other Notations
Other notations are emerging but not widely used yet. Some are domain specific, such as MetaH, and others are more general, such as Rapide. MetaH was designed
specifically
to support the development of real-time, fault-tolerant systems. Its primary emphasis is on
avionics
applications, although it has also been used to describe other types of systems. MetaH can be used in combination with ControlH, which is used to document and to analyze hardware systems. When used in combination, the system supports analysis of stability, performance, robustness,
schedulability
, reliability, and security.
Rapide has been designed to support the development of large, perhaps distributed, component-based systems. Rapide descriptions are stated in a textual format that can be translated into a box-and-arrow diagram of a set of connected components. System descriptions are composed of type specifications for component interfaces and architecture specifications for permissible connections among the
components
of a system. Rapide is an
event-based
simulation language that provides support for the dynamic addition and deletion of predeclared components, based on the observation of specified patterns of events during the execution of the system.
The Rapide toolset includes a graphical design environment that allows a designer to describe and to simulate a system. The result of a Rapide simulation is a
POSET,
a partially ordered set of events that form a trace of execution of the system. The simulation and analysis tools support exploring the correctness and completeness of the architecture.