Modeling
UML
| MIC
The ultimate goal of a software project is to put into production a system that meets or exceeds
the customer's expectations. This of course this implies the existence of working code.
In professional organizations code is developed by programmers working from
a set of architecture and design models.
The architecture and related analysis and design artifacts are necessary byproducts
of the development process; they are a means to and end, and not an
end it itself.
A software architecture is modeled using various UML (Unified Modeling Language) diagram types.
These diagrams must relate to one another in a logical and consistent manner and always reflect the current
state of the code. Some tool vendors (e.g. Borland and IBM) sell IDEs capable of maintaining consistency
between the model and the code, albeit not for all diagram types. This capability is often referred to
as "round-trip engineering".
Modern code editors allow the programmer to assign different colors to program elements such as keywords,
strings, and comments. Colors are also used to highlight things such as errors, warnings and differences.
Not surprisingly, the consistent use of color in a source code editor makes programming more efficient.
In a similar way, the use of 4-colors in software models makes software developers more efficient
by adding another dimension that increases semantic content, exposes useful patterns as well as modeling errors,
and helps reduce entropy. But color alone is not enough. We need to apply two other concepts:
"Archetypes" and the "Domain-Neutral Component". The modeling in color (MIC)
section provides the details of this method.
4 plus 1 architecture view
The top-level architecture model of a software-intensive
system is best described by five interlocking views: Use-case,
Design, Process, Implementation, and Deployment. The architecture is
decomposed into these five essential views in order to manage the
complexity associated with analyzing the problem, designing the
solution, and mapping the solution into an implementation.
At the center of this concept is the use-case view which drives
the development of the surrounding views. The use-case view is constructed to emulate the behavior desired by the user.
If developers use the requirements document containing statements
of the form, "The system shall ... this, The system shall ... that",
as the reference for programming then what you end up with is a
functional decomposition type-of-design which doesn't map naturally
to the problem domain nor does it take advantage of abstractions
provided in object-oriented programming languages. It also results
in more code then is necessary.
Each of the four views shown above provides a different window
into the behavior, organization, and structure of the system and
focuses on a particular aspect of the design. Each view can stand
alone so that different stakeholders can focus on the issues of the
system’s architecture that most concerns them.
Any UML diagram type may be used in a given view to serve
the purpose of capturing a requirement or a design decision, however, certain diagram types are specifically suited for in a
particular view. For example, the use-case view always has use-case,
sequence and communication diagrams. The design view always has
package, class, and object diagrams. The process view always has
activity and state-machine diagrams. The implementation view may
contain component diagrams but its main purpose is to show the
hierarchical organization of directories and packages and the
location of files within that hierarchy. The deployment view of a
system encompasses the nodes that form the system’s hardware
topology. This view addresses the distribution, delivery, and
installation of the parts that make up the physical system. The
static aspects of this view are captured in deployment and component
diagrams; the dynamic aspects of this view are captured in
interaction-overview, state-machine, and activity diagrams. These five
views are orthogonal to one other and yet they interact – nodes in
the deployment view hold components in the implementation view that
in turn, represent the physical realization of classes, interfaces,
collaborations, and active classes from the design and process
views.
Use-case view
Central to the discussion of a software process is the concept of
a use-case view, which is the starting point of any analysis and
design work since it describes the behavior of the system as seen
by its end users, analysts, testers, and implementers. The
emphasis of a use-case is on what the system does, rather than
how it does it. This view serves to specify the forces that will
shape the overall system architecture. Hence its location at the
middle of the diagram.
The use-case view is very helpful for determining features and
capturing requirements since new use-cases often generate new
requirements as the system is analyzed and the design takes
shape. Also, the notational simplicity makes use-case diagrams a
good vehicle for developers to communicate with clients, and the
collection of scenarios for a use-case may suggest a suite of
test cases for those scenarios.
A use-case represents a collection of scenarios for a single task
or goal. An actor is who or what initiates the events involved in
that task. Actors are simply roles that people or objects, (e.g.
an external sensor) play in the scenario.
Scenarios are closely connected to interaction diagrams.
Interaction diagrams emphasize the flow of control from object to
object. An interaction diagram is a single instance of a use-case
that implements a scenario by using collaborating objects drawn
from the solution domain to realize the scene. The behavior
described by a scenario validates the model if it is able to
successfully complete. That is to say, if an object or message in
the scenario is missing or incomplete then the scene will not be
able to successfully complete the task. At the code-level we
would say that the task would not execute. It is much more cost
effective to discover missing objects or deficient messages in the behavior model then it
is in the code.
Each use-case is represented by primary scenarios, (happy cases),
and secondary scenarios, when things go wrong. For every primary
scenario, there should be at least 3 or 4 secondary scenarios.
Scenarios should be kept relatively simple. An interaction
diagram used to validate a scenario should be able to fit on a
single A3 sheet of paper in landscape format. Where this is not
possible, the design is probably too complex and a redesign or
re-factoring is probably necessary.
The most important thing to remember when building use-case
models is that a use-case is not a function or a technical
specification, but rather conceptual models that describe a small
story about some way to use the system. Therefore, do not simply
denote all the things that the system needs to do, otherwise you
will end up with a functional decomposition, which is NOT the
purpose of a use-case. According to IBM, a use-case “defines
a sequence of actions performed by a system that yields an
observable result of value to an actor”. In other words, a good
use-case represents an identifiable business transaction that has
business value from the end-users perspective. Therefore, focus
on the value that the actor gets from the system and not on how
you can subdivide and structure the functionality. Your approach
must be opportunistic rather than deterministic, lateral rather
than linear. Technical requirements will appear in nested
use-case diagrams and also in
the functional and supplementary requirements specification
documents.
The real purpose of a use-case is to describe a story (a
case) of how someone or something will use the system to do something that is useful to them. It
describes what the system does at a conceptual level so that we
can understand enough to decide if the system will do the right
thing or not.
To select good use case names you need to focus on names that
reflect the goals of the actors; you must name use-cases from the
perspective of the actor, not the system. For example, Process
Ticket Order and Display Schedule are things the system does and
therefore, they are NOT good use-case names. Order Tickets and
View Schedule are goals of the system’s users and are thus good
use-case names.
To be successful at use-case modeling for the purpose of
exploring the interplay between the system and its actors you
must be able to think abstractly and have a high tolerance for
incompleteness. In other words, you must be able to stop thinking
linearly as if a use-case was a procedure, a flow chart, a
theorem, or a fault isolation manual. Just as some people cannot
see the hidden picture in a stereogram no matter how hard they
try, some developers (often excellent
programmers) cannot achieve the cognitive opaqueness needed to
create a meaningful use-case.
The static aspects of the use-case view are naturally captured in
use-case diagrams; the dynamic aspects of this view are captured
in interaction diagrams, activity
diagrams, and even state machine diagrams in special cases where it is
necessary to focus on an object undergoing a process.
Design view
The design view of a system encompasses the classes, interfaces,
and collaborations that form the vocabulary of the problem and
its solution. This view primarily supports the features that the
system must provide to its end users as well as the structural
requirements such as design patterns. Objects that appear in
use-case interaction diagrams are instances of the classes that
appear in the design view. The static aspects of this view are
captured in class diagrams, object diagrams, and package
diagrams; the dynamic aspects of this view are captured in
sequence/communication
diagrams, state-machine diagrams, and activity diagrams.
Process view
The process view encompasses the threads and
processes that form the system’s concurrency and synchronization
mechanisms. It describes the tasks involved in the system's
execution, their interactions and configurations, as well as the
allocation of objects and classes to tasks. Due to the impact on
performance, scalability, and throughput that the process view
has on the system, all architecturally significant processes must
be modeled.
Because activity diagrams are designed for modeling the dynamics
of business and system processes, they are especially valuable in
the process view to show the flow of control between activities
involved in a process and how these activities depend on one
another.
An activity is an artifact in the domain that represents a unit
of work. Each activity maps to an object at some level of
abstraction within the system. For example, this object could be
a subsystem, a component, or a class. If too many
activities are assigned to the same object then that object could
form a bottleneck and "overheat". Such hotspots can be detected
and measured with a runtime profiling tool. An analysis of the workflow distribution
in an activity model should allow you to avoid potential
hotspots.
In an activity diagram a "swim-lane" is provided for
each subsystem/component that appears in the process scenario.
The objective is to assign work to each component/class in such a way as to minimize
coupling between swim-lanes while at the same time distributing
work loads evenly (load balancing) to
prevent hotspots.
Activity diagrams emphasize the flow of control from activity to
activity and represent another way to describe a use-case
scenario. For example, in the use-case, “Withdraw money from a
bank account through an ATM”, we can identify objects and their
activities as follows: Customer.InsertCard, Customer.EnterPIN,
Bank.Authorize, Customer.EnterAmount, ATM.ShowBalance,
ATM.EjectCard, Customer.TakeCard, and so on. If the use-case
model is able to execute (at the analysis level) then the next
step is to create the corresponding activity diagram model to
illustrate the flow of control between objects and the
encapsulated units of work. The use-case scenario model and the
activity model represent the same information but from different
view points.
The static and dynamic aspects of the process view are captured
with the same kinds of diagrams as in the design view, but with
the focus on the active classes that represent the threads and
processes in the system.
Implementation view
The implementation view describes the decomposition of the
software system from the developer’s perspective. It establishes
the hierarchical organization of directories in terms of layers,
subsystems, components, classes, property-files, configuration-files, standard and
generic library components, and other artifacts needed to
assemble and release the physical system. This view also
addresses the configuration and deployment management of the
system’s releases which may be made up of somewhat independent
components and files and assembled in various ways to produce a
running system. Component diagrams are used to model static
aspects. Interaction, state-machine, and activity
diagrams are used to model dynamic aspects.
The screen shot below shows the directories that comprise the
implementation view of a project called CashSales. All UML
diagram files are located under the uml directory. Each
UML diagram is assigned to one of the five architecture views.
Project information not related to software development appears elsewhere in
the file system.
The same view from the modeling tool shows another perspective.
A more complex project such as one based on the JEE platform could
have a directory structure as show below. Note that each application (e.g.
Library-Manager), component and framework has its own source
directory (i.e. src) and package tree rooted at ch.bigelow. The
docroot directory is used to hold files belonging to the web
server.
Each JEE component is structured to contain specialized sub-packages.
Power tools
To work efficiently we need power tools and the availability of
an Integrated Development Environment (IDE) to keep code and
models in sync. For Java development Borland's Together is recommended because it uses the source code as the reference for
constructing UML diagrams instead of a meta-data repository. When
UML diagrams are derived from the source code the design model
reflects the state of the code and you have a single point of
maintenance. As a result, when you are modeling you are coding,
and when you are coding you are modeling.
Without such a tool to automatically keep the model and the code
in sync, producing UML diagrams amounts to basically just drawing
pictures which can only serve as a front-end activity to
jump-start a project. Once implementation begins, the design will
disappear into the code and diverge in different directions from
where it can no longer be observed and controlled. The failure of
other UML tools to keep model and code in sync (despite marketing
claims to the contrary) provides developers with a reasonably
good excuse to skip the analysis and design phase and just start
coding.
Summary
At
the heart of object oriented problem solving is the construction
of a model.
Object-oriented programming is
about developing an executable
implementation of a design model.
An
design model that cannot be executed has no practical value.
The
use of color in both code and models improves developer
efficiency.
The
top-level architecture model is best described by five
interlocking views.
A
functional decomposition type-of-design doesn't map naturally to
the problem domain.
A
use-case represents a collection of scenarios for a single task
or goal.
It
is much more cost effective to discover missing objects or
deficient messages in the behavior model then it is in the code.
Objects
that appear in use-case interaction diagrams are instances of
the classes that appear in the design view.
The
process view encompasses the threads and processes that form the
system’s concurrency and synchronization mechanisms.
Activity
diagrams emphasize the flow of control from activity to activity
and represent another way to describe a use-case scenario.
The
implementation view describes the decomposition of the system
from the developer’s perspective.
Without
a tool to automatically keep the model and the code in sync,
producing UML diagrams amounts to basically just drawing
pictures which can only serve as a front-end activity to
jump-start a project.