Preview of Patterns in Java Volume 2
Volume 2 of my patterns book contains patterns that apply to phases of
the software development cycle other than design. Synopses of the
design patterns in volume 1
are available on a separate page. I have begun work on Volume 3. There
is a preliminary outline for volume
3.
There is also an errata page for
Volume 2.
The 50 patterns in volume 2 are organized into categories as shown in
the following table:
If you have any suggestions about this page or would like to discuss a
pattern with its author, send e-mail to mgrand@mindspring.com
.
GRASP Patterns
GRASP is an acronym for General Responsibility Assignment Software Patterns.
GRASP Patterns provide guidance for assigning responsibilities to classes
and, to a limited extent, determining the classes that will be in a design.
This book discusses GRASP patterns as they are applied to object oriented
design. Most GRASP patterns apply equally well to business process reengineering.
During analysis, when you are building a conceptual model of an organization
that has more than one way to do something, GRASP patterns can provide
guidance in selecting paths through the organization to include in the
conceptual model.
-
Low Coupling/High Cohesion
If you find that a class is so highly coupled or lacking in cohesion
as to make a design brittle or difficult to modify, then apply other appropriate
GRASP patterns to reassign the class’ responsibilities.
Related patterns are
-
Interface
One form of coupling between classes is the coupling between a subclass
and its superclass. It is often possible to avoid subclassing by using
the Interface pattern.
-
Mediator
It is not necessary or even always desirable for all of the classes
in a design to have low coupling and high cohesion. Sometimes the overall
complexity of a class can be reduced by concentrating complexity in one
class. The Mediator pattern provides an example of that.
-
Composed Method
It is possible for methods to be uncohesive and difficult to work with.
Some common causes are excessive length or too many execution paths within
a method. The Composed Method pattern provides guidance of breaking up
such methods into smaller, simpler and more cohesive methods.
-
Expert
Assign a responsibility to the class that has the information needed
to carry out the responsibility.
Related patterns are
-
Low Coupling/High Cohesion
The Expert pattern promotes low coupling by putting methods in the
classes that have the information that the methods need. Classes whose
methods only need the class’ own information have less need to rely on
other classes. A set of methods that all operate on the same information
tends to be cohesive.
-
Creator
Determine which class should create instances of a class based on the
relationship between the potential creator classes and the class to be
instantiated.
-
Polymorphism
When alternate behaviors are selected based on the type of an object,
use a polymorphic method call to select the behavior, rather than using
if statements to test the type.
Related patterns are
-
Dynamic Linkage
You can implement plug-ins or pluggable software components using a
combination of polymorphism and the Dynamic Linkage pattern.
-
Pure Fabrication
Fabricate a class that does not represent a problem domain entity when
you must assign a responsibility to a class, but assigning it to a class
that represents a problem domain entity would ruin its low coupling or
high cohesion.
Related patterns are
-
Low Coupling/High Cohesion
The point of the Pure Fabrication pattern is to maintain the low coupling
and high cohesion of the classes in an object oriented design.
-
Law of Demeter
If two classes have no other reason to be directly aware of each other
or otherwise coupled, then the two classes should not directly interact.
Instead of having a class call the methods of another class that it has
no other reason to be coupled with, it should call that method indirectly
through another class. Insisting on such indirection keeps a design’s overall
level of coupling down.
Related patterns are
-
Low Coupling/High Cohesion
The fundamental motivation for the Don’t Talk to Strangers pattern
is to maintain low coupling.
-
Pure Fabrication
There are sometimes good reasons for calls made to classes added to
a design using the Pure Fabrication pattern to violate the guidelines of
the Don’t Talk to Strangers pattern.
-
Mediator
The Mediator pattern provides an example of a class created through
pure fabrication that receives direct method calls from classes unrelated
to it with a benefit that outweighs the disadvantages of the direct calls.
Controller
If a program will receive events from external sources other
than its graphical user interface, add an event class to decouple the event
source(s) from the objects that actually handle the events.
Related patterns are
-
Pure Fabrication
The Controller pattern is a specialized form of the Pure Fabrication
pattern.
-
Mediator
The Mediator pattern is used to coordinates events from a GUI.
Like controller objects, a highly coupled and incohesive mediator
object may involve less overall complexity than an arrangement that distributes
the same responsibilities over more objects.
GUI Design Patterns
-
Window Per Task
A GUI should have a separate window for each cohesive task a
user must perform. All information needed to perform the task is available
from the window. The application provides a way to navigate between windows
that allows the coordination of tasks.
Related patterns are
-
Interaction Style
Match the style of interaction offered by a GUI to the abilities
of its users and the requirements of the application. The most common styles
of interaction are Selection, Form, Direct Manipulation and Conversational
Text.
Related patterns are
-
Conversational Text
This pattern describes one of the interaction styles that this pattern
promotes.
-
Form
This pattern describes one of the interaction styles that this pattern
promotes.
-
Direct Manipulation
This pattern describes one of the interaction styles that this pattern
promotes.
-
Selection
This pattern describes one of the interaction styles that this pattern
promotes.
-
Explorable Interface
Design user interaction to be forgiving of the user’s mistakes by allowing
the user to undo actions and go back to previous decision points.
Related patterns are
-
Command
The Command pattern describes a way to undo the effects of a command
or the performance of a task.
-
Conversational Text
The Explorable Interface pattern is often used with the Conversational
Text pattern.
-
Form
The Explorable Interface pattern is often used with the Form pattern.
-
Supplementary Window
The Explorable Interface pattern is often used with the Supplementary
Window pattern.
-
Direct Manipulation
The Explorable Interface pattern is often used with the Direct Manipulation
pattern.
-
Selection
The Explorable Interface pattern is often used with the Selection pattern.
-
Snapshot
The Snapshot pattern can be used to restore the state of a program
to what it was at a previous time.
-
Conversational Text
Design a GUI to accept commands in the form of textual input.
Related patterns are
-
Explorable Interface
The Interaction Style pattern is used to decide to use the Conversational
Text pattern.
-
Interaction Style
The Interaction Style pattern is used to decide to use the Conversational
Text pattern.
-
Little Language
The Little Language pattern describes how to design and implement textual
command input as a little language.
-
Selection
Allow users to interact with a GUI by selecting commands and data values
from lists.
Related patterns are
-
Explorable Interface
The Explorable Interface pattern describes a technique for making
a selection interaction more useable.
-
Limited Selection Size
The Limited Selection Size pattern provides additional guidance in
determining the presentation of a menu interaction.
-
Form
Allow a user to enter structured data into a GUI as discrete pieces
of information.
Related patterns are
-
Ephemeral Feedback
The Ephemeral Feedback pattern provides guidance in providing brief,
short lived feedback to a user.
-
Explorable Interface
The Explorable Interface pattern describes a technique for making a
data entry form interaction more useable.
-
Selection
Data Entry Form interactions often include selection interactions to
select data values.
-
Direct Manipulation
Allow users to interact with objects by manipulating representation
of objects presented by a GUI.
Related patterns are
-
Ephemeral Feedback
The Ephemeral Feedback pattern provides guidance in providing brief,
short lived feedback to a user.
-
Explorable Interface
The Explorable Interface pattern describes a technique for making a
direct manipulation interaction more useable.
-
Selection
When a direct manipulation interaction that supports Menus are used
to select a command to manipulate previously selected objects.
-
Limited Selection Size
Design the presentation of selection interactions to avoid displaying
more than a limited number of choices at a time.
Related patterns are
-
Selection
The Limited Selection Size pattern provides guidance on designing the
presentation of selection interactions.
-
Ephemeral Feedback
Provide feedback to users about the status of their work, without interfering
with the natural flow of their work.
Related patterns are
-
Ease of Use
Use of the Ephemeral Feedback pattern can result in a GUI that presents
uses with fewer surprises, which the Ease of Use pattern says is a good
thing.
-
Disabled Irrelevant Things
Hide or disable GUI elements that that are not relevant in the
current context.
Related patterns are
-
Selection
The Disabled Irrelevant Things pattern is used with the Selection pattern.
-
Supplementary Window
Display a window for a user interaction that supplements a parent window’s
interaction. The purpose of the supplementary window is to collect information
for the parent window’s interaction, display additional information about
the parent window’s interaction or provide a notification about the status
of the parent’s interaction. The supplementary window is shorter lived
than its parent.
Related patterns are
-
Limited Selection Size
Use the Limited Selection Size pattern to decide if a dialog will have
pull-down menus.
-
Window Per Task
The Supplementary Window Pattern is partially motivated by the Window
Per Task pattern.
-
Step-by-Step Instructions
Lead a user through the steps of a task, so that the GUI tells the
user what to do next, rather than the user telling the GUI what to do next.
Related patterns are
-
Selection
Implementations of the Step-by-Step Instructions pattern usually rely
heavily on selection interactions to acquire information from users.
-
Supplementary Window
Sometimes the Step-by-Step Instructions pattern is used to supplement a
GUI that requires the user to lead the program through tasks. Wizards that
are available in popular word processing and spreadsheet programs are an
example. When the Step-by-Step instructions pattern is used to design a
supplementary GUI, it is usually in the context of a dialog.
Organizational Coding Patterns
The patterns in this chapter provide guidance in organizing your code
in ways that promote readability and maintainability. A principle that
underlies many of these patterns is that simple code is easier to understand
and less likely to contain bugs.
-
Accessor Method Name
Use names and signatures for accessor methods that are easy to read
and conform to the JavaBeans specification.
-
Anonymous Adapter
Use anonymous adapter objects to handle events. This simplifies the
code and allows code relating to the same event source to be in the same
part of the source code.
Related patterns are
-
Adapter
The Anonymous Adapters pattern uses Adapter objects.
-
Mediator
If handling events from multiple sources involves managing or
using common or interrelated state information, then the Mediator pattern
may provide a better way to handle the events.
-
Hashed Adapter Objects
You can use the hashed Adapter Objects pattern to provide a more flexible
way to manage event handlers than the Anonymous Adapters pattern.
-
Symbolic Constant Name
Use symbolic names for constants. A meaningful name makes the
purpose of the constant clear to someone reading the code. Symbolic names
can also simplify maintenance.
Related patterns are
-
Immutable
The Immutable pattern describes other uses for immutable objects.
-
Switch
Code that uses the Switch pattern should also use the Symbolic Constant
Name pattern.
-
Define Constants in Interfaces
Avoid having to qualify symbolic constant names with the name of the
class that defines them. Define them in an interface. That way, any class
that implements the interface can use the symbolic names without any qualification.
Related patterns are
-
Switch
Select a piece of code to execute from multiple alternatives based
on an int data value by using a switch statement.
Related patterns are
-
Hashed Adapter Objects
Switch statements associate int values pieces of code. The
Hashed Adapter Objects pattern associates objects with pieces of code.
-
Symbolic Constant Name
Code that uses the Switch pattern should also use the Symbolic Constant
Name pattern.
-
Polymorphism
In many situations, polymorphic method calls are a more appropriate
technique than switch statements. However, people with a background in
procedural programming who are new to object oriented techniques often
use switch statements when polymorphic method calls would be more appropriate.
-
Extend Super
Implement a method that modifies the behavior of a superclass’ method
by calling the superclass’ method.
Related patterns are
-
Composed Method
The Composed Method pattern describes the more general case of composing
the behavior of a method from the behavior of other methods.
-
Template Method
The Template Method pattern describes a way to design a class that
plans for its behavior to be extended by a subclass’s methods. It provides
more flixibility and control over how a subclass extends the behavior of
its superclass than the Extend Super pattern at the expense of greater
complexity. In particular, the Template Method patterns allows behavior
of a subclass to occur in the middle of the exection of superclass’s methods.
The template method pattern can also be used to force a subclass to extend
a superclass in predefined ways.
-
Intention Revealing Method
If the intention of a call to a general purpose method is not obvious,
then define a method with a meaningful name to call the general purpose
method.
Related patterns are
-
Intention Revealing Method
The sort of methods described by the Intention Revealing Method pattern
should be the smallest methods that you create when applying the Composed
Method pattern.
-
Composed Method
The Composed Method pattern provides other reasons for moving
code into a separate method.
-
Façade
After applying the Composed Method pattern, you may decide to break
a class up into smaller classes with the original class acting as a façade.
-
Conditional Compilation
Control whether a compiler includes statements for debugging in the
byte codes it generates or ignores those statements.
Related patterns are
-
Assertion Testing
The Conditional Compilation pattern is often used with the Assertion
Testing pattern.
-
White Box Testing
The Conditional Compilation pattern is often used with the White Box
Testing pattern.
-
Composed Method
Reorganize methods that are too large to easily understand into smaller
methods.
Related patterns are
-
Intention Revealing Method
The sort of methods described by the Intention Revealing Method pattern
should be the smallest methods that you create when applying the Composed
Method pattern.
-
Maximize Privacy
The Maximize Privacy pattern provide the motivation for making sub-methods
private that are created by applying the Composed Method pattern.
Façade
-
After applying the Composed Method pattern, you may decide to break a class
up into smaller classes with the original class acting as a façade.
-
Checked Versus
Unchecked Exceptions
As part of its contract with its callers, a method may be expected
to throw exceptions under certain circumstances. Those exceptions should
be checked exceptions. Any exceptions a method throws that are outside
of its contract, such exceptions to indicate internal errors or to help
with debugging, should be unchecked exceptions.
Related patterns are
-
Assertion Testing
The Assertion Testing pattern provides additional guidance about checked
or unchecked exception to report unsatisfied assertions.
-
Conditional Compilation
The Conditional Compilation pattern can be used to prevent debug code
that throws unchecked exceptions from being included in a production version
of a class.
-
Convert Exceptions
Many programs are organized into layers related to different domains,
such as database management and an application domain. In such programs,
some classes are part of one domain but have methods that call methods
of classes that belong to another domain. Such methods should convert exceptions
they do not catch from the other domain to their own domain.
Related patterns are
-
Server Socket
You need to write code to manage the server side of a socket based
network connection. The code that you write follows a very consistent pattern
that revolves around ServerSocket and Socket objects.
Related patterns are
-
Client Socket
The Client Socket pattern described the common logic for implementing
clients.
-
Thread Pool
The Thread Pool pattern describes a more efficient way to to manage
server threads. The Thread Pool pattern will be described in Volume 3.
-
Two Phase Termination
The Two Phase Termination pattern explains how to use a Thread object’s
interrupt method to request that the thread show down in an orderly manner.
-
Client Socket
Most uses of the Socket class to implement a client follow a very consistent
coding pattern.
Related patterns are
-
Heartbeat
The Heartbeat pattern (described in Volume 3) describes a technique
that allows a client program to detect that a server has gone down.
-
Server Socket
The ServerSocket pattern described the common logic for implementing
servers.
Code Optimization Patterns
The patterns in this chapter can be used to improve the performance
of a program in ways that a compiler’s automatic optimizations cannot accomplish.
Like any other kind of optimization, you should use the patterns in this
chapter only after you have established a definite need for them. For example,
the Loop Unrolling pattern reduces the amount of time required to execute
a loop. It does so at the expense of making the code larger and harder
to understand and maintain. If the program makes enough loop iterations
for a small reduction in the duration of each iteration to produce a noticeable
improvement, that is a good application of the Loop Unrolling pattern.
If applying the Loop Unrolling pattern does not produce a noticeable improvement,
then you have made you program more difficult to understand an maintain
with no corresponding benefit.
The usual way to determine what to optimize is to run a program using
a good execution profiling tool. Such tools are able to tell you how much
time a program spends in different methods or statements. They are also
able to indicate the percentage of time that the program spent in each
place and the number of times that each statement or method was executed.
-
Hashed Adapter Objects
Dispatch a method call to an adapter object associated with an arbitrary
object. The arbitrary object is used to find the adapter object in a hash
table. The Hashed Adapter Objects pattern is most commonly used when an
object must be created from unencapsulated data or unencapsulated data
must be dispatched to an object.
Related patterns are
-
Adapter
The Hashed Adapter Objects pattern uses Adapter objects.
-
Lookup Table
Both the Hashed Adapter Objects pattern and the Lookup Table pattern
involve the use of an aggregation. However, the aggegation serves a different
purpose for each. The Lookup Table pattern uses an aggregation of precomputed
results to save the time it would take to compute those results in the
future. For the Hashed Adapter Objects pattern, it is that data structure
that implements the aggregation that is the source of the time savings.
-
Polymorphism
When it is possible to select a behavior based on the type of an object,
the Polymorphism pattern produces a simpler result than the Hashed Adapter
Objects pattern.
-
Single Threaded
Execution
The Single Threaded Execution pattern is used to coordinate access
by multiple threads to the hash table used by the Hashed Adapter Objects
pattern.
-
Strategy
The Hashed Adapter Objects pattern can used to design the selection
of strategy objects in the Strategy pattern.
-
Lazy Initialization
Delay the creation of an object or other expensive action needed to
initialize a variable until it is known that the variable will be used.
Related patterns are
-
Maximize Privacy
The Maximize Privacy pattern provides a justification for making a
lazily initialized variable private.
-
Virtual Proxy
Like the Lazy Initialization pattern, the Virtual Proxy pattern can
be used to delay a computation or the creation of an object until it is
actually needed. The difference is that the Virtual Proxy pattern uses
a proxy object to hide the computation; the Lazy Initialization pattern
uses a method to hide the computation.
-
Double Checked Locking
A multi-threaded program does not initialize a resource until
it actually needs the resource. One thread recognizes that that resource
is not yet initialized when another thread has already begun the initialization.
Avoid duplicating the initialization effort by coordinating the actions
of multiple threads.
Related patterns are
-
Balking
The Balking design pattern is usually implemented using the same if-synchronized-if
structure as the Double Checked Locking pattern.
-
Lazy Initialization
The Double Checked Locking pattern can be used to ensure the integrity
of the Lazy Initialization pattern when it is used in multi-threaded application.
-
Singleton
The Double Checked Locking pattern can be used in a thread safe and
efficient implementation of the Singleton pattern.
-
Virtual Proxy
The Double Checked Locking pattern can be used in a thread safe
implementation of the Virtual Proxy pattern.
-
Loop Unrolling
Reduce the overhead of a loop’s control logic by increasing the amount
of work it does in each iteration so that it can accomplish the same amount
of work in fewer iterations. This pattern trades memory for speed.
-
Lookup Table
Save the memory consumed by complex code and the time it takes to execute
by precomputing the results and putting them in a lookup table.
Related patterns are
-
Hashed Adapter Objects
Both the Hashed Adapter Objects pattern and the Lookup Table pattern
involve the use of an aggregation. However, the aggegation serves a different
purpose for each. The Lookup Table pattern uses an aggregation of precomputed
results to save the time it would take to compute those results in the
future. For the Hashed Adapter Objects pattern, it is that data structure
that implements the aggregation that is the source of the time savings.
Robustness Coding
Patterns
-
Assertion Testing
Verify that a method conforms to its contract with its callers by inserting
code to test its preconditions, postconditions, invariants and data conditions
and run time.
Related patterns are
-
Checked vs. Unchecked Exceptions
The Checked vs. Unchecked Exception pattern explains reasons for using
unchecked exceptions to indicate assertion failures.
-
Conditional Compilation
You can use the Conditional Compilation pattern with the Assertion
Testing pattern to control whether or not assertion testing code is included
in a particular configuration of a program.
-
Guaranteed Cleanup
Ensure that internal data are in a consistent state if an operation
is unable to execute to its normal completion. Ensure that external resources
are consistent state and, if appropriate, released after an operation is
unable to execute to its normal completion.
-
Maximize Privacy
Make members of classes as private as possible.
Related patterns are
-
Return New Objects
from Accessor Method
Accessor methods return values or objects that indicate an object’s
state. If the objects that an accessor method returns are mutable, then
they should be copies rather than the actual state determining objects.
That prevents changes to the returned object from also changing the state
of the accessor method’s associated object.
Related patterns are
-
Copy Mutable Parameters
The Return New Objects from Accessor Method pattern avoids the situation
of an object sharing its state determining objects with callers of its
accessor methods. The Copy Mutable Parameters pattern avoids a similar
situation with callers that pass state determining objects into its constructors
and methods.
-
Copy Mutable Parameters
Objects may be passed to a method or constructor that will be used
to determine the state of its associated object. If the passed objects
are mutable, then copies of them should be used to determine the object’s
state, rather than the original passed object. That prevents changes to
the passed object from also changing the state of the object associated
with the method or constructor.
Related patterns are
-
Return New Objects from
Accessor Method
The Copy Mutable Parameters pattern avoids the situation of an object
sharing its state determining objects with callers of its methods that
specify those objects. The Return New Objects from Accessor Method pattern
avoids a similar situation with callers of methods that return state determining
objects.
Testing Patterns
-
White Box Testing
White box testing is used more often at the unit testing level than
at larger levels of granularity. This is because at the unit testing level
there are fewer combinations of execution paths to consider. It is also
because white box testing at the unit level makes classes easier to reuse
and lowers long term software maintenance costs.
-
Integration Testing
Test individually developed classes together for the first time.
Related patterns are
-
System Testing
Integration testing generally involves testing smaller groups of classes
than you test during system testing. Integration testing can be considered
an activity that smooths the transition from not being sufficiently along
in the development cycle to do system testing to a situation where system
testing is a productive activity.
-
Unit Testing
Unit testing deals with individual classes or very small groups of
classes. System Testing deals with larger groups of classes.
-
System Testing
Test a program as a whole entity, in an environment similar to the
one it is intended to be run in, to ensure that it conforms to its specifications.
Related patterns are
-
Integration Testing
Integration testing ensures that the software being tested is in a
sufficiently functional state that it is possible to run groups of system
tests and get meaningful results.
-
Regression Testing
Regression testing allows you to use system tests to monitor the progress
of programmers and to measure the overall readiness of the software to
meet its requirements and specifications.
-
Regression Testing
Keep track of the outcomes of testing software with a suite of tests
over time. This allows you to monitor the progress of programmers in completing
their coding as they make incremental changes. It allows you to determine
if a change to a program introduced new bugs.
Related patterns are
-
Systems Testing
Regression testing is commonly used with system testing.
-
Unit Testing
Regression testing is sometimes used with unit testing.
-
Acceptance Testing
Acceptance testing is testing done to ensure that delivered software
meets the needs of the customer or organization that the software was developed
for. Such testing is usually performed by the organization that the software
was developed for. Acceptance testing is done according to a plan. The
purpose of an acceptance testing plan is to ensure that software developers
and the organization that they develop a software system for agree on when
the software is ready to be delivered by developers.
Related patterns are
-
Systems Testing
System testing is often the final form of testing that a software developer
performs on software before turning it over to the developer’s customer
for acceptance testing.
-
Clean Room Testing
People designing software should not discuss specifications or their
implementation with people designing tests for the software.
Return to Mark Grand's home page.