- The name of the class clearly reflects the role it plays.
- The description of the class clearly conveys the purpose of
- The class represents a single well-defined abstraction.
- The class's attributes and operations are all essential to
fulfilling the responsibilities of the class.
- Each class represents a small, consistent and unique set of
- The responsibilities of the class are well-defined, clearly
stated, and clearly related to the purpose of the class.
- Each class is relatively self-contained, and is loosely
coupled to other classes.
- The responsibilities of the class are at a consistent level
of abstraction (i.e. high-level (application-level) and low-level
(implementation-level) responsibilities are not mixed).
- Classes in the same inheritance hierarchy possess unique
class attributes, operations and relationships (i.e. they inherit all
common attributes, operations and relationships).
- The complete life-cycle of an instance of the class is
accounted for. Each object is created, used, and removed by one or more
- The class satisfies the behavioral requirements established
by the use-case realizations.
- All requirements on the class in the requirement
specification are addressed.
- The demands on the class (as reflected in the class
description and by the objects in sequence diagrams) are consistent with
the class's state machine.
- All responsibilities of the class are related, such that it
is not possible for the class to exist in a system where some of its
responsibilities are used, but not others.
- No two classes have essentially the same purpose.
- The generalization hierarchy is balanced, such that there are
no classes for which the hierarchy is unusually flat or deep.
- Obvious commonality has been reflected in the inheritance
- There are no superclasses which appear to be merges of the
attributes of the subclasses.
- There are no intermediate abstract classes in the inheritance
hierarchy with orthogonal properties, examples of which include duplicated
subclasses on both sides of an inheritance tree.
- Inheritance is used to capture common design abstractions,
not primarily for implementation considerations, i.e. to reuse bits of
code or class structure.
- The name of each operation is descriptive and understandable.
- The state machine and the operations are
- The state machine and operations completely
describe the behavior of the class.
- The parameters of each operation are correct
in terms of both number, name and type.
- Implementation specifications for each
operation, where defined, are correct.
- Operation signatures conform to the standards
of the target programming language.
- Each operation is used by at least one
- All relationships of the class are required to support some
some operation of the class.
- Each attribute represents a single conceptual thing.
- The name of each attribute is descriptive, and correctly
conveys the information it stores.
- The role names of aggregations and associations describe the
relationship between the associating and associated classes.
- The multiplicities of the relationships are correct.
- The state machine is as simple as possible while still
expressing the required behavior.
- The state machine does not contain any superfluous states or
- The state machine has a clear context.
- All referenced objects are visible to the enclosing object.
- The state machine is efficient, and carries out its behavior
with an optimal balance of time and resources as defined by the actions it
- The state machine is understandable.
- The state and transition names are understandable in the
context of the domain of the system.
- The state names indicate what is being waited for or what
is happening, rather than what has happened.
- The state and transition names are unique within the state
machine (although not a strict requirements, it aids in debugging to
enforce unique names).
- Logical groupings of states are contained in composite
- Composite states have been used effectively to reduce
- Transition labels reflect the underlying cause of the
- There are no code fragments on state transitions which are
more than 25 lines of detail code; instead, functions have been used
effectively to reduce transition code complexity.
- State machine nesting has been examined to ensure that
nesting depth is not too deep to be understandable; one or two levels of
substates are usually sufficient for most complex behaviors.
- Active classes have been used instead of
concurrent substates; active classes are nearly always a better alternative and
more understandable than concurrent substates.
- In real-time systems, capsules have been
used to represent logical threads of control.
- Error or maintenance states have been accounted for.
- Substates have been used in lieu of extended state variables;
there is no evidence of transition guard conditions testing several
variables to determine which to state the transition should occur.
- The state machine does not resemble a flow chart.
- The state machine does not appear to have been overly
de-composed, consisting of nested state machines with a single sub-state.
In cases where the nested sub-state is a placeholder for future design
work or subclassing, this may be temporarily acceptable providing that the
choice has been a conscious one.
© 1987 - 2001 Rational Software Corporation