Strategy:
One of the most useful patterns
for controlling code entropy, the Strategy pattern is great when an object
needs to start behaving in a conditionally different manor. The classic
example is a sorting class. This takes a strategy that is used to define
the sort algorithm to use. Different strategies can be applied for linear
or bubble sort etc. The sorting class has no knowledge of the strategy
implementation, it just calls sort(). Thus it is
easy to change the sorting algorithm without influencing sorter class.
A variant on this
pattern is the Policy. The Policy pattern is a strategy that has a group of
methods that are implemented differently to express different behavioural
types. This is useful for creating a generic class that can behave
differently for different users (as an alternative to subclassing).
For example a screen might have a policy with the methods; getTitle(),
performOk(), performCancel()
on its Policy. It is thus easy to reuse this control specifying different
policies for different implementations.
State:
State is quite similar
to Strategy. The state pattern dictates that an objects response to its
primary methods (on an interface) should be delegated to a state class.
This state class then has several implementations according to the
different states that the class can be in. Like strategy, this allows
different behavioural responses to be encapsulated. For example a button
might have three states, each state might dictate a different colour and caption.
If the state of the button was constant then you would likely use a
Strategy, inserted on initialisation. However if the state of the button
changes dynamically a state pattern would facilitate this (as the
‘strategy’ for each state is changed dynamically by putting the button into
a certain state).
Proxy:
The proxy pattern
provides a surrogate place holder for another object so that access to that
object can be controlled. The proxy looks (and behaves) exactly like a real
object. However its underlying implementation is different. For example a
client application may be given a proxy object so that calls to the server
can be mediated (batched, cached, pooled etc). This is applied by many component
frameworks. Alternatively proxies can be used for administrative tasks such
as controlling access (security). Proxy and Decorator are really similar
structurally, however they perform different roles. Proxy controls access
whilst decorator augments behaviour.
Composite:
Compose objects in to
tree structures to represent part-whole hierarchies. Composite lets clients
treat individual objects as compositions of objects uniformly. Thus printing
the top of the tree might print the whole thing whilst printing a node
would only print that node. The node and the tree are all viewed through
the same composite interface as single elements.
Adaptor:
Converts (adapts) the
interface of one class to that of the other.
Façade:
A façade is an object
that provides a simplified interface to a larger body of code.
Decorator:
Augment the
functionality of an object by wrapping it in a new object that has the same
interface. The original object is then a delegate inside the decorating
one. Functionality can then be added to the decorating class (this makes a
good alternative to extension). Decorators can chain. The various streams,
readers and writers in the java.io package are a
good example of this.
Command:
A step on from
encapsulating an action in a function is to encapsulate it in a class. By
doing so various actions can be passed to clients. The pattern also allows
undo operations (by tracking the undo operation for the last action) as
well as aiding logging and queuing.
Factory
(Method):
Factory Method decouples
the creational routines from the implementation and as such decouples the application.
There are two important parts of this pattern:
(1) The type of object
produced is defined by an interface not a class. This means that the
implementation can be varied through polymorphism decoupling the impelementaiton of the interface from the classes that
will be using it. Great if you want to change the implementation or say use
Mock objects for testing purposes.
(2) For the Factory
Method form of the pattern the factory itself is generally abstract with
different sub classes that provide the creational routines. This can be
extended to produce a Template Method for the creational process.
Abstract Factory takes this idea further by having the creations
routine use a variety of polymorphic entities that are supplied by the
implementation of each abstract factory. So for example a salad factory
would have interfaces for Tomato, Lettuce and Dressing. One factory might
return cherry tomato, iceberg and thousand island whilst the other returned
regular tomato, rocket and French dressing.
Builder:
Builder is similar to factory except that it is loaded with objects
prior to the constructional call. This is useful the make-up of an object
is tied to the domain logic that is creating it or a series of, potentially null objects are supplied before
construction.
Chain of Responsibility:
Allows calls to be made through a hierarchy of objects with each
object either handling the request or passing it on to its successor. Analogous
to an exception that is either dealt with or thrown. Also used a lot in
windowing systems for handling events like mouse clicks.
|