0% found this document useful (0 votes)
8 views

Design Patterns

The document discusses various design patterns including Builder, Factory, Prototype, Abstract Factory, Singleton, and Object Pool patterns, outlining their implementation considerations, design considerations, and pitfalls. Each pattern is explained with examples and scenarios where they are applicable, emphasizing the importance of understanding when to use each pattern effectively. The document also highlights common challenges and best practices associated with these design patterns.

Uploaded by

m.hajni.m
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

Design Patterns

The document discusses various design patterns including Builder, Factory, Prototype, Abstract Factory, Singleton, and Object Pool patterns, outlining their implementation considerations, design considerations, and pitfalls. Each pattern is explained with examples and scenarios where they are applicable, emphasizing the importance of understanding when to use each pattern effectively. The document also highlights common challenges and best practices associated with these design patterns.

Uploaded by

m.hajni.m
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 54

Builder pattern

Implementation Considerations
- You can easily create an immutable class by implementing builder as an inner static
class. You’ll find this type of implementation used quite frequently even if
immutability is not a main concern.
this way setter methods can be declared private for the outer class

Design Considerations
- The director role is rarely implemented as separate class, typically the consumer of
the object instance or the client handles that role.
- Abstract builder is also not required if "product" itself is not part of any
inheritance hierarchy. You can directly create concrete builder.
- If you are running into a ”too many constructor arguments” problem then it’s a
good indication that builder pattern may help.

° The java.langStringBuilder class as well as various buffer classes in java.nio


package like ByteBuffer, CharBuffer are often given as examples of builder pattern.
- In my humble opinion they can be given as examples of builder pattern, but with an
understanding that they don't match 100% with GoF definition. These classes do allow us
to build final object in steps, providing only a part of final object in one step. In
this way they can be thought of as an implementation of builder pattern.
- So a StringBuilder satisfies the intent/purpose of builder pattern. However as soon
we start looking at structure of the StringBuilder things start to fall apart. GoF
definition also states that, builder has potential to build different
representations of product Interface using same steps.

Another good example is Calendar.Builder

Pitfalls
- A little bit complex for new comers mainly because of 'method chaining’, where
builder methods return builder object itself.
- Possibility of partially initialized object; user code can set only a few or none
of properties using with methods and call build(). If required properties
are missing, build method should provide suitable defaults or throw exception.

Simple factory pattern

-move the instantiation logic to a separate class and most commonly to a static method of this class

-some do not consider it a design patter, as its simply a method that encapsulates object instantiation

-typically we want to do this if we have more than one option when instantiating object and a simple logic is used to
choose the correct class
- Simple factory encapsulates away the object instantiation in a separate method.
- We can pass an argument to this method to indicate product type and/or additional
arguments to help create objects
Factory pattern

What is a Factory Method?


- We want to move the object creation logic from our code to a separate class.
- We use this pattern when we do not know in advance which class we may need to
instantiate beforehand & also to allow new classes to be added to system and
handle their creation without affecting client code.
- We let subclasses decide which object to instantiate by overriding the factory
method.

Implement a Factory Method


We start by creating a class for our creator
- Creator itself can be concrete if it can provide a default object or it can be
abstract.
- Implementations will override the method and return an object

Implementation Considerations
- The creator can be a concrete class & provide a default implementation for the
factory method. In such cases you'll create some "default" object in base creator.
- You can also use the simple factory way of accepting additional arguments to choose
between different object types. Subclasses can then override factory method to
selectively create different objects for some criteria.
Design Considerations
- Creator hierarchy in factory method pattern reflects the product hierarchy. We
typically end up with a concrete creator per object type.
- Template method design pattern often makes use of factory methods.
- Another creational design pattern called 'abstract factory" makes use of factory
method pattern.
Pitfalls
- More complex to implement. More classes involved and need unit testing.
- You have to start with Factory method design pattern from the beginning. It’s not
easy to refactor existing code into factory method pattern.
- Sometimes this pattern forces you to subclass just to create appropriate instance.
Prototype pattern

What IS a Prototype?
- We have a complex object that is costly to create. To create more Instances of such
class we use an existing instance as our prototype.
- Prototype will allow us to make copies of existing object and save us from having to
recreate objects from scratch.
Implement a Prototype
We start by creating a class which will be a prototype
- The class must implement Cloneable interface
- Class should override clone method and return copy of itself.
- The method should declare CloneNotSupportedException in throws clause to give
subclasses chance to decide on whether to support cloning.

Clone method implementation should consider the deep & shallow copy and
choose whichever is applicable.
shallow copy vs deep copy
char * Source = "Hello, world.";

char * ShallowCopy = Source;

char * DeepCopy = new char(strlen(Source)+1);


strcpy(DeepCopy,Source);

'ShallowCopy' points to the same location in memory as 'Source' does. 'DeepCopy' points to a different
location in memory, but the contents are the same.

Implementation Considerations
-Pay attention to the deep copy and shallow copy of references. Immutable fields on
clones save the trouble of deep copy.
-Make sure to reset the mutable state of object before returning the prototype. It's a
good idea to implement this in method to allow subclasses to initialize themselves.
-clone() method is protected in Object class and must be overridden to be public to be
callable from outside the class.
-Cloneable is a "marker" interface, an indication that the class supports cloning.
Design Considerations
- Prototypes are useful when you have large objects where majority of state is
unchanged between instances and you can easily identify that state.
- A prototype registry is a class where in you can register various prototypes
which other code can access to clone out instances. This solves the issue of
getting access to initial instance.
Example of a Prototype
- Actually the Object.clone() method is an example of a prototype!
- This method is provided by Java and can clone an existing object, thus allowing any
object to act as a prototype. Classes still need to be Cloneable but the method does
the job of cloning object.
Pitfalls
- Usability depends upon the number of properties in state that are immutable or can be
shallow copied. An object where state is comprised of large number of mutable objects
is complicated to clone.
- In java the default clone operation will only perform the shallow copy so if you need
a deep copy you've to implement it.
- Subclasses may not be able to support clone and so the code becomes complicated as
you have to code for situations where an implementation may not support clone.
ln-A-Hurry Summary
- Think of prototype pattern when you have an object where construction of a new
instance is costly or not possible (object is supplied to your code).
- In Java we typically implement this pattern with clone method.
- Objects which have a majority of their state as immutable are good candidates for
prototypes.
- When implementing clone method pay attention to the requirement of deep or shallow
copy of object state.
- Also we’ve to insure that clone is ”initialized”; that is appropriate states are
reset before returning the copy to outside world.

Abstract factory pattern

What IS an Abstract Factory?


- Abstract factory is used when we have two or more objects which work together forming
a kit or set and there can be multiple sets or kits that can be created by client code.
- So we separate client code from concrete objects forming such a set and also from the
code which creates these sets.
Implementation Abstract Factory
- We start by studying the product ”sets”
- Create abstract factory as an abstract class or an interface.
- Abstract factory defines abstract methods for creating products.
- Provide concrete implementation of factory for each set of products.
- Abstract factory makes use of factory method pattern. You can think of abstract
factory as an object with multiple factory methods...
Implementation Considerations
- Factories can be implemented as singletons, we typically ever need only one instance
of it anyway. But make sure to familiarize yourself with drawbacks of singletons.
- Adding a new product type requires changes to the base factory as well as all
implementations of factory.
- We provide the client code with concrete factory so that it can create objects
Design Considerations
- When you want to constrain object creations so that they all work together then
abstract factory is good design pattern.
- Abstract factory uses factory method pattern.
- If objects are expensive to create then you can transparently switch factory
implementations to use prototype design pattern to create objects.
Example
- The javax. xml.parsers.DocumentBuilderFactory is a good example of an abstract
factory pattern. However this implementation doesn’t match 100% with the UML of
abstract factory from GoF. The class has a static newInstance() method which returns
actual factory class object.
- The newInstance() method however uses classpath scanning, system properties, an
external property file as ways to find the factory class and creates the factory
object. So we can change the factory class being used, even if this is a
static method.

Pitfalls
- A lot more complex to implement than factory method.
- Adding a new product requires changes to base factory as well as ALL implementations
of factory.
- Difficult to visualize the need at start of development and usually starts out as a
factory method.
- Abstract factory design pattern is very specific to the problem of ”product
families”.
In-A—Hurry Summary
- When you have multiple sets of objects where objects in one set work together then
you can use abstract factory pattern to isolate client code from concrete objects and
their factories.
- Abstract factory itself uses factory method pattern and you can think of them as
objects with multiple factory methods.
- Adding a new product type needs changes to base factory and all its implementations.
- Concrete factories can be singleton as we need only one instance of them in code.
- We provide client code with concrete factory instance. Factories can be changed at
runtime.
Singleton pattern

What is a Singleton?
- A singleton class has only one instance, accessible globally through a single point
(via a method/field)
- Main problem this pattern solves is to ensure that only a single instance of this
class exists
- Any state you add in your singleton becomes part of ”global state” of your
application
Implement singleton
Controlling instance creation
- Class constructor(s) must be not be accessible globally
- Subclassing/inheritance must not be allowed
Keeping track of instance
- Class itself is a good place to track the instance
Giving access to the singleton instance
- A public static method is good choice
- Can expose instance as final public static field but it won’t work for all singleton
implementations
Implement a Singleton
Two options for implementing a singleton
- Early initialization — Eager Singleton
Create singleton as soon as class is loaded
- Lazy initialization — Lazy Singleton
Singleton is created when it is first required
Implementation Considerations
- Early/Eager initialization is the simplest & preferred way. Always try to use this
approach first.
- The ”classic” singleton pattern implementation uses double check locking and volatile
field.
- The lazy initialization holder idiom provides best of both worlds, you don’t deal
with synchronization issues directly and is easy to implement.
- You can also implement singletons using enums. However due to pre-conceptions about
what an enum is, it may be a hard sell during code review especially if singleton has
mutable fields.
- If the simple solution works then use it!
Design Considerations
- Singleton creation does not need any parameters. If you find yourself in need of
support for constructor arguments, you need a simple factory or factory method
pattern instead.
- Make sure that your singletons are not carrying a lot of mutable global state.

Pitfalls
- Singleton pattern can deceive you about true dependencies! Since they are globally
accessible it’s easy to miss dependencies.
- They are hard to unit test. You cannot easily mock the instance that is returned.
- Most common way to implement Singletons in Java is through static variables and they
are held per class loader and not per JVM. So they may not be truly Singleton in an
OSGi or web application.
- A Singleton carrying around a large mutable global state is a good indication of an
abused Singleton pattern.
Summary
- Singleton pattern is used when you want to ensure that only one instance of a class
exists in application.
- In Java we achieve this by making constructor private, this also prevents inheritance
and providing a public static method which returns the singleton instance
Implementation wise we have two broad choices —
1. In eager loading singleton, we create instance as soon as class is loaded by
classloader.
2. In lazy loading singleton, we defer creation until some code actually requests the
instance.
- Always prefer the eager loading instance unless creation cost is high and start-up
time impact is noticeable.
In—A—Hurry Summary
- There are very few situations where a Singleton is really a good choice.
- Application configuration values can be tracked in a singleton. Typically these
are read from file at start and then referred to by other parts of application.
- Logging frameworks also make use of Singleton pattern.
- Spring framework treats all beans by default as singletons. In spring we don’t
have to make any changes to ensure single instance, Spring handles that for us.

Object pool pattern

What is an Object Pool?


- In our system if cost of creating an instance of a class is high and we need a large
number of objects of this class for short duration, then we can use an object pool.
- Here we either pre-create objects of the class or collect unused instances in an in
memory cache. When code needs an object of this class we provide it from this cache.
- One of the most complicated patterns to implement efficiently (& without defects©)
Implement
We start by creating class for object pool
- A thread-safe caching of objects should be done in pool.
- Methods to acquire and release objects should be provided & pool should reset cached
objects before giving them out.
The reusable object must provide methods to reset its state upon ”release” by code.
We have to decide whether to create new pooled objects when pool is empty or to wait
until an object becomes available. Choice is influenced by whether the object is tied
to a fixed number of external resources.

Implementation Considerations
- Resetting object state should NOT be costly operation otherwise you may end up losing
your performance savings.
- Pre-caching objects; meaning creating objects in advance can be helpful as it won’t
slow down the code using these objects. However it may add-up to start up time & memory
consumption.
- Object pool’s synchronization should consider the reset time needed to avoid
resetting in synchronized context if possible.
Design Considerations
- Object pool can be parameterized to cache & return multiple objects and the acquire
method can provide selection criteria.
- Pooling objects is only beneficial if they involve costly initialization because of
initialization of external resource like a connection or a thread. Don’t pool objects
JUST to save memory, unless you are running into out of memory errors.
- Do not pool long lived objects or only to save frequent call to new. Pooling may
actually negatively impact performance in such cases.
Examples
- Using object pool for saving the memory allocation & GC cost is almost deprecated
now. JVMs & hardware are more efficient & have access to more memory now.
- However it is still a very common pattern when we are interacting with external
resources like threads, connections.
- java.util.concurrent.ThreadPoolExecutor is an example of object pool pattern which
pools threads. Even though we can directly use this class, you’ll often use it via
ExecutorSerVice interface using method like Executors like newCachedThreadPool().

- Apache commons dbcp library is used for database connection pooling. Class
org.apache.commons.dbcp.BasicDataSource in dbcp package is an example of object pool
pattern which pools database connections. This pool is commonly created and exposed via
JNDI or as a Spring bean in applications.

Pitfalls
- Successful implementation depends on correct use by the client code. Releasing
objects back to pool can be vital for correct working.
- The reusable object needs to take care of resetting its state in efficient way. Some
objects may not be suitable for pooling due to this requirement.
- Difficult to use in refactoring legacy code as the client code & reusable object both
need to be aware of object pool.
- You have to decide what happens when pool is empty and there is a demand for an
object. You can either wait for an object to become free or create a new object. Both
options have issues. Waiting can have severe negative impact on performance.
- If you create new objects when code asks for an object and none are available then
you have to do additional work to maintain or trim the pool size or else you'll end up
with very large pool.
Summary
- Objects to be pooled should provide a method to ”reset” their state so they can be
reused. This operation should be efficient as well, otherwise release operation will be
costly.
- Pool must handle synchronization issues efficiently and reset object state before
adding them to pool for reuse.
- Client code must release pooled objects back into the pool so they can be reused.
Failing to do so will break the system. Thread pools can work around this since a
thread can know when its work is done.
- Difficult to optimize as pools are sensitive to system load at runtime (demand of
pooled objects).
- Pools are good choice when the pooled objects represent a fixed quantity of
externally available resource like thread or a connection.

Structural patterns

Adapter pattern

What is Adapter?
- We have an existing object which provides the functionality that client needs. But
client code can’t use this object because it expects an object with different
interface.
- Using adapter design pattern we make this existing object work with client by
adapting the object to client’s expected interface.
- This pattern is also called as wrapper as it ”wraps” existing object.
Implement an Adapter
- We start by creating a class for Adapter
- Adapter must implement the interface expected by client.
- First we are going to try out a class adapter by also extending from our existing
class.
- In the class adapter implementation we’re simply going to forward the method to
another method inherited from adaptee.
- Next for object adapter, we are only going to implement target interface and accept
adaptee as constructor argument in adapter i.e. make use of composition.
- An object adapter should take adaptee as an argument in constructor or as a less
preferred solution, you can instantiate it in the constructor thus tightly coupling
with a specific adaptee.
Implementation Considerations
- How much work the adapter does depends upon the differences between target interface
and object being adapted. If method arguments are same or similar adapter has very less
work to do.
- Using class adapter ”allows” you to override some of the adaptee’s behaviour. But
this has to be avoided as you end up with adapter that behaves differently than
adaptee. Fixing defects is not easy anymore!
- Using object adapter allows you to potentially change the adaptee object to one of
its subclasses.
Design Considerations
- In java a “class adapter” may not be possible if both target and adaptee are concrete
classes. In such cases the object adapter is the only solution. Also since there is no
private inheritance in Java, it’s better to stick with object adapter.
- A class adapter is also called as a two way adapter, since it can stand in for both
the target interface and for the adaptee. That is we can use object of adapter where
either target interface is expected as well as where an adaptee object is expected.
Example
- The java.io.inputStreamReader and java.io.OutputStreamWriter classes are examples of
object adapters.
- These classes adapt existing InputStream/OutputStream object to a Reader/Writer
interface.

Pitfalls
- Using target interface and adaptee class to extend our adapter we can create a ”class
adapter” in java. However it creates an object which exposes unrelated methods in parts
of your code, polluting it. Avoid class adapters! It is mentioned here only for sake of
completeness.
- It is tempting to do a lot of things in adapter besides simple interface translation.
But this can result in an adapter showing different behaviour than the adapted object.
- Not a lot of other pitfalls! As long as we keep them true to their purpose of simple
interface translation they are good.
In—A—Hurry Summary
- We have an existing object with required functionality but the client code is
expecting a different interface than our object.
- A class adapter is one where adapter inherits from class of object which is to be
adapted and implements the interface required by client code. This adapter type should
be avoided.
- An object adapter uses composition . It’ll implement the target interface and use an
adaptee object composition to perform translation. This allows us to use subclasses of
adaptee in adapter.
Bridge pattern

What is Bridge?
- Our implementations & abstractions are generally coupled to each other in normal
inheritance.
- Using bridge pattern we can decouple them so they can both change without affecting
each other.
- We achieve this feat by creating two separate inheritance hierarchies; one for
implementation and another for abstraction.
- We use composition to bridge these two hierarchies.
Implement a Bridge
We start by defining our abstraction as needed by client
- We determine common base operations and define them in abstraction.
- We can optionally also define a refined abstraction & provide more specialized
operations.
- Then we define our implementor next. Implementor methods do NOT have to match with
abstractor. However abstraction can carry out its work by using implementor methods
- Then we write one or more concrete implementor providing implemention
Abstractions are created by composing them with an instance of concrete implementor
which is used by methods in abstraction.
Implementation consideration
- In case we are ever going to have a single implementation then we can skip creating
abstract implementor.
- Abstraction can decide on its own which concrete implementor to use in its
constructor or we can delegate that decision to a third class. In last approach
abstraction remains unaware of concrete implementors & provides greater de-coupling.
Design Considerations
- Bridge provides great extensibility by allowing us to change abstraction and
implementor independently. You can build & package them separately to modularize
overall system.
- By using abstract factory pattern to create abstraction objects with correct
implementation you can de-couple concrete implementors from abstraction.
Example of a Bridge
An example of bridge pattern often given is the JDBC API. More specifically the
java.sql.DriverManager class with the java.sq|.Driver interface form a bridge pattern.

Another example of bridge pattern often given is the Collections.newSetFromMap()


method. This method returns a Set which is backed by given map object.
Pitfalls
- It is fairly complex to understand & implement bridge design pattern.
- You need to have a well thought out & fairly comprehensive design in front of you
before you can decide on bridge pattern.
- Needs to be designed up front. Adding bridge to legacy code is difficult. Even for
ongoing project adding bridge at later time in development may require fair amount
of rework.
In-A-Hurry Summary
- We use bridge pattern when we want our abstractions and implementations to be
decoupled.
- Bridge pattern defines separate inheritance hierarchies for abstraction &
implementations and bridge these two together using composition.
- Implementations do not HAVE to define methods that match up with methods in
abstraction.It is fairly common to have primitive methods; methods which do small work;
in implementor. Abstraction uses these methods to provide its functionality.
Decorator pattern

What is Decorator?
- When we want to enhance behaviour of our existing object dynamically as and when
required then we can use decorator design pattern.
- Decorator wraps an object within itself and provides same interface as the wrapped
object. So the client of original object doesn’t need to change.
- A decorator provides alternative to subclassing for extending functionality of
existing classes.

Implement a Decorator
- We start with our component.
- Component defines interface needed or already used by client.
- Concrete component implements the component.
- We define our decorator. Decorator implements component & also needs reference to
concrete component.
- In decorator methods we provide additional behaviour on top that provided by concrete
component instance
- Decorator can be abstract as well & depend on subclasses to provided functionality.
Implementation Consideration
- Since we have decorators and concrete classes extending from common component, avoid
large state in this base class as decorators may not need all that state.
- Pay attention to equals and hashCode methods of decorator. When using decorators, you
have to decide if decorated object is equal to same instance without decorator.
- Decorators support recursive composition, and so this pattern lends itself to
creation of lots of small objects that add ”just a little bit” functionality. Code
using these objects becomes difficult to debug.
Desing Considerations
- Decorators are more flexible & powerful than inheritance. Inheritance is static by
definition but decorators allow you to dynamically compose behaviour using objects at
runtime.
- Decorators should act like additional skin over your object. They should add helpful
small behaviours to object’s original behaviour. Do not change meaning of operations.
Examples
- Classes in Java’s I/O package are great examples of decorator pattern.
- For example the java.io.BufferedOutputStream class decorates anyjava.io.0utputStream
object and adds buffering to file writing operation. This improves the disk i/o
performance by reducing number of writes.

Pitfalls
- Often results in large number of classes being added to system, where each class adds
a small amount of functionality. You often end up with lots of objects, one nested
inside another and so on.
- Sometimes new comers will start using it as a replacement of inheritance in every
scenario. Think of decorators as a thin skin over existing object.
In-A-Hurry Summary
- We use decorator when we want to add small behaviour on top of existing object.
- A decorator has same interface as the object it decorates or contains.
- Decorators allow you to dynamically construct behaviour by using composition. A
decorator can wrap another decorator which in turn wraps original object.
- Client of object is unaware of existence of decorator.
Composite pattern

What is Composite?
- We have a part-whole relationship or hierarchy of objects and we want to be able to
treat all objects in this hierarchy uniformly.
- This is NOT a simple composition concept from object oriented programming but a
further enhancement to that principal.
- Think of composite pattern when dealing with tree structure of objects.

Implement a Composite
We start by creating an abstract class / interface for Component
- Component must declare all methods that are applicable to both leaf and composite.
- We have to choose who defines the children management operations, component or
composite.
- Then we implement the composite. An operation invoked on composite is propagated to
all its children
- In leaf nodes we have to handle the non-applicable operations like add/remove a child
if they are defined in component.
- In the end, a composite pattern implementation will allow you to write algorithms
without worrying about whether node is leaf or composite.
Implementation Considerations
- You can provide a method to access parent of a node. This will simplify traversal of
the entire tree.
- You can define the collection field to maintain children in base component instead of
composite but again that field has no use in leaf class.
- If leaf objects can be repeated in the hierarchy then shared leaf nodes can be used
to save memory and initialization costs. But again the number of nodes is major
deciding factor as using a cache for small total number of nodes may cost more.
Design Considerations
- Decision needs to be made about where child management operations are defined.
Defining them on component provides transparency but leaf nodes are forced to implement
those methods. Defining them on composite is safer but client needs to be made aware of
composite.
- Overall goal of design should be to make client code easier to implement when using
composite. This is possible if client code can work with component interface only and
doesn’t need to worry about leaf-composite distinction.
Example
- Composite is used in many Ul frameworks, since it easily allows to represent a tree
of Ul controls.
- In JSF we have UlViewRoot class which acts as composite. Other UIComponent
implementations like UlOutput, UlMessage act as leaf nodes.

Pitfalls
- Difficult to restrict what is added to hierarchy. If multiple types of leaf nodes are
present in system then client code ends up doing runtime checks to ensure the operation
is available on a node.
- Creating the original hierarchy can still be complex implementation especially if you
are using caching to reuse nodes and number of nodes are quite high.
ln—A—Hurry Summary
- We have a parent-child or whole-part relation between objects. We can use composite
pattern to simplify dealing with such object arrangements.
- Goal of composite pattern is to simplify the client code by allowing it to treat the
composites and leaf nodes in same way.
- Composites will delegate the operations to its children while leaf nodes implement
the functionality.
- You have to decide which methods the base component will define. Adding all methods
here will allow client to treat all nodes same. But it may force classes to implement
behaviour which they don’t have.

Facade pattern

What is Facade?
- Client has to interact with a large number of interfaces and classes in a subsystem
to get result. So client gets tightly coupled with those interfaces & classes. Facade
solves this problem.
- Facade provides a simple and unified interface to a subsystem. Client interacts with
just the facade now to get same result.
- Facade is NOT just a one to one method forwarding to other classes.
Implement a Facade
We start by creating a class that will serve as a facade
- We determine the overall ”use cases”/tasks that the subsystem is used for.
- We write a method that exposes each ”use case" or task.
- This method takes care of working with different classes of subsystem.
Implementation Considerations
- A facade should minimize the complexity of subsystem and provide usable interface.
- You can have an interface or abstract class for facade and client can use different
subclasses to talk to different subsystem implementations.
- A facade is not replacement for regular usage of classes in subsystem. Those can be
still used outside of facade. Your subsystem class implementations should not make
assumptions of usage of facade by client code.
Design Considerations
- Facade is a great solution to simplify dependencies. It allows you to have a weak
coupling between subsystems.
- If your only concern is coupling of client code to subsystem specific classes and not
worried about simplification provided by a facade, then you can use abstract factory
pattern in place of facade.

Example
- The java.net.URL class is a great example of facade. This class provides a simple
method called as openStreamO and we get an input stream to the resource pointed at by
the URL object.
- This class takes care of dealing with multiple classes from the java.net package as
well as some internal sun packages.
Pitfalls
- Not a pitfall of the pattern itself but needing a facade in a new design should
warrant another look at API design.
- It is often overused or misused pattern & can hide improperly designed API. A common
misuse is to use them as ”containers of related methods”. So be on the lookout for such
cases during code reviews.
In—A—Hurry Summary
- We use facade when using our subsystem requires dealing with lots of classes 8:
interfaces for client. Using facade we provide a simple interface which provides same
functionality.
- Facade is not a simple method forwarding but facade methods encapsulate the subsystem
class interactions which otherwise would have been done by client code.
Facades are often added over existing legacy codes to simplify code usage & reduce
coupling of client code to legacy code.

Flyweight pattern

- Our system needs a large number of objects of a particular class & maintaining these
instances is a performance concern.
- Flyweight allows us to share an object in multiple contexts. But instead of sharing
entire object, which may not be feasible, we divide object state in two parts:
intrinsic (state that is shared in every context) & extrinsic state (context specific
state). We create objects with only intrinsic state and share them in multiple
contexts.
- Client or user of object provides the extrinsic state to object to carry out its
functionality.
- We provide a factory so client can get required flyweight objects based on some key
to identify flyweight.
Implementation steps
- We start by identifying ”intrinsic” & ”extrinsic” state of our object
- We create an interface for flyweight to provide common methods that accept extrinsic
state
- In implementation of shared flyweight we add intrinsic state & also implement
methods.
- In unshared flyweight implementation we simply ignore the extrinsic state argument as
we have all state withinobject.
- Next we implement the flyweight factory which caches flyweights & also provides
method to get them
- In our client we either maintain the extrinsic state or compute it on the fly when
using flyweight
Implementation Consnderations
- A factory is necessary with flyweight design pattern as client code needs easy way to
get hold of shared flyweight. Also number of shared instances can be large so a central
place is good strategy to keep track of all of them.
- Flyweight’s intrinsic state should be immutable for successful use of flyweight
pattern.
Design Considerations
- Usability of flyweight is entirely dependent upon presence of sensible extrinsic
state in object which can be moved out of object without any issue.
- Some other design patterns like state and strategy can make best use of flyweight
pattern.
Examples of a Flyweight
- Java uses flyweight pattern for Wrapper classes like java.lang.lnteger, Short, Byte
etc. Here the valueOf static method serves as the factory method.

- String pool which is maintained by JVM is also an example of flyweight. We can call
the intern() method on a String object to explicitly request this String object to be
interned. This method will returned a reference to already cached object if present or
else will create new String in cache if not present.(string.intern() is a native
method)
Pitfalls
- Runtime cost may be added for maintaining extrinsic state. Client code has to either
maintain it or compute it every time it needs to use flyweight.
- It is often difficult to find perfect candidate objects for flyweight. Graphical
applications benefit heavily from this pattern however a typical web application may
not have a lot of use for this pattern.
In—A-Hurry Summary
- We use flyweight design pattern if we need large number of objects of class where we
can easily separate out state that can be shared and state that can be externalized.
- Flyweights store only ”intrinsic” state or state that can be shared in any context.
- Code using flyweight instance provides the extrinsic state when calling methods on
flyweight. Flyweight object then uses this state along with its inner state to carry
out the work.
- Client code can store extrinsic per flyweight instance it uses or compute it on the
fly.
Proxy pattern

We need to provide a placeholder or surrogate to another object.


Proxy acts on behalf of the object and is used for lots of reasons some of the main
reasons are:
- Protection Proxy - Control access to original object’s operations
- Remote Proxy — Provides a local representation of a remote object
- Virtual proxy - Delays construction of original object until absolutely necessary
Client is unaware of existence of proxy. Proxy performs its work transparently.

Lazy loading of collections by hibernate, APO based method level security, RMI/Web
service stubs are examples of real life proxy usage.
Implement
- We start by implementing proxy
- Proxy must implement same interface as the real subject
- We can either create actual object later when required or ask for one in
constructor.
- In method implementations of proxy we implement proxy’s functionality before
delegating to real object
- How to provide client with proxies instance is decided by application. We can provide
a factory or compose client code with proxies instance.
- What we are implementing above is also called as static proxy. Java also provides
”dynamic proxies”
Implement a Dynamic Proxy
We start by implementing java.lang.reflect.InvocationHandler
° Invocation handler implements invoke method which is called to handle every method
invocation on proxy
° We need to take action as per the method invoked. We’ll cache the Method instances on
image interface so that we can compare them inside invoke method
° Our invocation handler will accept same argument in constructor as needed by
constructor of real object
Actual proxy instance is created using java.lang.reflect.Proxy by client.
Implementation Considerations
- How proxy gets hold of the real object depends on what purpose proxy serves. For
creation on demand type of proxies; actual object is created only when proxy can’t
handle client request. Authentication proxies use pre-built objects so they are
provided with object during construction of proxy.
- Proxy itself can maintain/cache some state on behalf of real object in creation on
demand use cases.
- Pay attention to performance cost of proxies as well synchronization issues added by
proxy itself.
Design Considerations
- Proxies typically do not need to know about the actual concrete implementation of
real object.
- With Java you can use dynamic proxy allowing you to create proxies for any object at
runtime.
- Proxies are great for implementing security or as stand-ins for real objects which
may be a costly object that you wa nt to defer loading. Proxies also make working with
remote services/APls easy by representing them as regular objects and possibly handling
network communications behind the scene.
Examples of a Proxy
- This is one pattern where you’ll ?nd numerous examples ©
- Hibernate uses a proxy to load collections of value types. If you have a relationship
in entity class mapped as a collection, marked as candidate for lazy loading then
Hibernate will provide a virtual proxy in its place.
- Spring uses proxy pattern to provide support for features like transactions, caching
and general AOP support.
- Hibernate & spring both can create proxies for classes which do not implement any
interface. They use third party frameworks like cglib, aspect] to create dynamic
proxies (remember, Java’s dynamic proxy needs interface) at runtime.

Pitfalls
- Java’s dynamic proxy only works if your class is implementing one or more interfaces.
Proxy is created by implementing these interfaces.
- If you need proxies for handling multiple responsibilities like auditing,
authentication, as a stand-in for the same instance, then it’s better to have a single
proxy to handle all these requirements. Due to the way some proxies create object on
their own, it becomes quite difficult to manage them.
- Static proxies look quite similar to other patterns like decorator & adapter
patterns. It can be confusing to figure it out from code alone for someone not familiar
with all these patterns.
Summary
- We want a stand in or placeholder object or we want control access to our objects
method, then we can use proxy pattern.
- Proxy implements same interface as expected of real object. It delegates actual
functionality to real object. Proxies are either given real object or they create one
when needed. Some proxies talk to remote service behind the scene.
- Main usage of proxies is for:
-Protection Proxy - Control access to original object's operations
- Remote Proxy — Provides a local representation of a remote object.
- Virtual proxy — Delays construction of original object until absolutely
necessary
- In java we can also use dynamic proxies. These are created on the fly at runtime.
Behavioral patterns

Chain of responsability pattern

What is Chain of Responsability?


- We need to avoid coupling the code which sends request to the code which handles that
request.
- Typically the code which wants some request handled calls the exact method on an
exact object to process it, thus the tight coupling. Chain of responsibility solves
this problem by giving more than one object, chance to process the request.
- We create objects which are chained together by one object knowing reference of
object which is next in chain. We give request to first object in chain, if it can’t
handle that it simply passes the request down the chain.
Implement Chain of responsibility
- We start by defining handler interface/abstract class
- Handler must define a method to accept incoming request
- Handler can define method to access successor in chain. If it’s an abstract class
then we can even maintain successor
- Next we implement handler in one or more concrete handlers. Concrete handler should
check if it can handle the request. If not then it should pass request to next handler.
- We have to create our chain of objects next. We can do it in client. Typically in
real world this job will be done by some framework or initialization code written by
you.
- Client needs to know only the first object in chain. It’ll pass on request to this
object.
Implementation Considerations
-Prefer defining handler as interface as it allows you to implement chain of
responsibility without worrying about single inheritance rule of Java.
- Handlers can allow the request to propagate even if they handle the request. Servlet
filter chains allow request to flow to next filter even if they perform some action on
request.
- Chain can be described using XML or JSON as well so that you can add & remove
handlers from chain without modifying code.
Design Considerations
- Sometimes you can think of using existing connections or chains in objects. For
example if you are using composite pattern you already have a chain which can be used
to implement this behavior.

Example of a Chain of responsibility


- Probably the best example of chain of responsibility is servlet filters. Each filter
gets a chance to handle incoming request and passes it down the chain once its work is
done.
- All servlet filters implement the javax.servlet.F_i|_t_g interface which defines
following doFilter method public void doFilter(ServletRequest request, ServletResponse
response, FilterChain chain)
- Implementations will use FilterChain object to pass request to next handler in chain
i.e. chain.doFi|ter(request, response);
- In servlet filters, it’s common practice to allow other filters to handle request
even if current filter takes some action on the request.

Pitfalls
- There is no guarantee provided in the pattern that a request will be handled. Request
can traverse whole chain and fall off at the other end without ever being processed and
we won’t know it.
- It is easy to misconfigure the chain when we are connecting successors. There is
nothing in the pattern that will let us know of any such problems. Some handlers may be
left unconnected to chain.
In—A-Hurry Summary
- When we want to decouple sender of request from the object which handles the request,
we use chain of responsibility.
- We want this decoupling because we want to give multiple objects chance to handle the
request & we don’t know all objects before hand.
- A handler checks if it can handle the request. If it can’t then it’ll pass the
request on to next handler in chain.
- You can pass the request down the chain even if a handler handles the request. Design
pattern doesn’t prevent that from happening.

Command pattern

What is a Command?
- We want to represent a request or a method call as an object. Information about
parameters passed and the actual operation is encapsulated in a object called command.
- Advantage of command pattern is that, what would have been a method call is now an
object which can be stored for later execution or sent to other parts of code.
- We can now even queue our command objects and execute them later.
Implementation Comsiderations
- You can support ”undo” & ”redo” in your commands. This makes them really useful for
systems with complex user interactions like workflow designers.
- If your command is simple i.e. if it doesn’t have undo feature, doesn’t have any
state & simply hides a particular function & its arguments then you can reuse same
command object for same type of request.
- For commands that are going to be queued for long durations, pay attention to size of
state maintained by them.
Design considerations
- Commands can be inherited from other commands to reuse portions of code and build
upon the base.
- You can also compose commands with other commands as well. These ”macro” commands
will have one or more sub-commands executed in sequence to complete a request.
- For implementing undo feature in your command you can make use of memento design
pattern, which allows command to store the state information of receiver without
knowing about internal objects used by receiver.
Example of Command Pattern
The java.lang.Runnable interface represents the Command pattern.
- We create the object of class implementing runnable, providing all information it
needs.
- In the run method we’ll call an operation on the receiver.
- We can send this object for later execution to other parts of our application.

The Action class in struts framework is also an example of Command pattern. Here each
URL is mapped toa action class. We also configure the exact no-arg method in that class
which is called to process that request.

Pitfalls
- Things get a bit controversial when it comes to returning values & error handling
with command. ©
- Error handling is difficult to implement without coupling the command with the
client. In cases where client needs to know a return value of execution it’s the same
situation.
- In code where invoker is running in a different thread, which is very common in
situations where command pattern is useful, error handling & return values get lot more
complicated to handle.
In—A—Hurry Summary
- Command pattern allows you to treat requests for operations as objects. This allows
you to send these objects to different parts of code for later execution or to a
different thread.
- Commands typically invoke the actual operation on a receiver but contain parameters
or information needed for invocation.
- Client code is responsible for creating instances of command & providing it with
receiver and request information.
- Commands can also implement an undo feature. Here command itself stores a snapshot of
receiver.
Command pattern

Interpreter pattern

What is an Interpreter?
- We use interpreter when want to process a simple ”language” with rules or grammar.
- E.g. File access requires user role and admin role.
- Interpreter allows us to represent the rules of language or grammar in a data
structure and then interpret sentences in that language.
- Each class in this pattern represents a rule in the language. Classes also provide a
method to interpret an expression.
Implement interpreter
- We start by studying rules of the language for which we want to build interpreter
- We define an abstract class or interface to represent an expression & define
a method in it which interprets the expression.
- Each rule in the class becomes an expression. Expressions which do not need
other expressions to interpret become terminal expressions.
- We then create non-terminal expression classes which contain other
expressions. These will in turn call interpret on children as well as perform
interpretation of their own if needed.
- Building the abstract syntax tree using these classes can be done by client itself or
we can create a separate class to do it.
- Client will then use this tree to interpret a sentence.
- A context is passed to interpreter. It typically will have the sentence to be
interpreted & optionally it may also be used by interpreter to store any values which
expressions need or modify or populate.
Implementation Considerations
- Apart from interpreting expressions you can also do other things like pretty printing
that use already built interpreter in new way.
- You still have to do the parsing. This pattern doesn’t talk about how to actually
parse the language & build the abstract syntax tree.
- Context object can be used to store & access state of the interpreter.
Design Considerations
- You can use visitor pattern to interpret instead of adding interpret method in
expression classes. Benefit of this is that if you are using multiple operations on the
abstract syntax tree then visitor allows you to put these operations in a separate
class.
- You can also use flyweight pattern for terminal expressions. You’ll often ?nd that
terminal expressions can be reused.
Examples
- The java.util.regex.Pattern class is an example of interpreter pattern in Java class
library.
° Pattern instance is created with an internal abstract syntax tree, representing the
grammar rules, during the static method call compile(). After that we check a sentence
against this grammar using Matcher.

- Classes supporting the Unified Expression Language (EL) in JSP 2.1 JSF 1.2. These
classes are in javax.el package. We have javax.el.Expression as a base class for value
or method based expressions. We have javax.el.ExpressionFactory implementations to
create the expressions. javax.el.ELResolver and its child classes complete the
interpreter implementation.
Pitfalls
- Class per rule can quickly result in large number of classes, even for moderately
complex grammar.
- Not really suitable for languages with complex grammar rules.
- This design pattern is very specific to a particular kind of problem of interpreting
language.
In-a-hurry summary
- When we want to parse a language with rules we can use the interpreter pattern.
- Each rule in the language becomes an expression class in the interpreter pattern. A
terminal expression provides implementation of interpret method. A non-terminal
expression holds other expressions and calls interpret on its children.
- This pattern doesn’t provide any solution for actual parsing and building of the
abstract syntax tree. We have to do it outside this pattern.
Mediator pattern

What is mediator?
- Mediator encapsulates how a set of objects interact with each other. Due to this
encapsulation there is a loose coupling between the interacting objects.
- Typically an object explicitly knows about other object to which it wants to interact
i.e. to call a method. In mediator pattern this interaction is within the mediator
object & interacting objects only know about the mediator object.
- Benefit of this arrangement is that the interaction can now change without needing
modifications to participating objects. Changing the mediator allows to add/remove
participants in an interaction.
Implement mediator
-We start by defining mediator
- Mediators define a generic method which is called by other objects.
- This method typically needs to know which object changed and optionally the
exact property which has changed in that object.
- We implement this method in which we notify rest of the objects about the
state change.
- Mediator needs to know about all participants in the collaboration it is mediating.
To solve this problem we can either have objects register with mediator or mediator
itself can be the creator of these objects
- Depending upon your particular implementation you may need to handle the infinite
loop of change-notify-change which can result if object’s value change handler is
called for every value change whether from an external source as well as mediator

Implementation considerations
- It’s important that mediator can identify which object has sent change notification
to avoid sending that object the changed value again.
- If an object method took a very long time to process the change it can affect overall
performance of mediator severely. In fact this is a common problem in any notification
system, so pay attention to synchronization in mediator methods.
- We often end up with a complex mediator since it becomes a central point which ends
up handling all routing between objects. This can make it a very difficult to maintain
the mediator as the complexity grows.
Design Considerations
- We can extend a mediator and create variations to be used in different situations
like platform dependent interactions.
- Abstract mediator is often not required if the participating objects only work with
that one mediator.
- We can use observer design pattern to implement the notification mechanism through
which objects notify the mediator.
Examples
- Defining characteristic of mediator is: it streamlines the communication between
multiple objects. 50 a class which simply calls methods on multiple objects can’t be a
mediator confirming 100% to gof mediator definition.
- The javax.swing.ButtonGroup class is an example of mediator. It takes care of making
sure that only button in a group is selected. Participating “Buttons” notify this
mediator when they are selected.

-Sometimes a front controller is given as an example of mediator pattern. E.g. The


DispatcherServlet in Spring.

- Purpose of front controller is to act as a central point where requests from outside
world can land and then they are forwarded to appropriate page controller, often by use
of some form of URL to class mapping.
- Front controller pattern can be thought of as a specialized version of mediator
pattern. Front controller satisfies mediator characteristics like acting as central hub
for communication between objects. It is specialized since it also handles requests
from outside system & performs lookup to find a specific controller which will handle
the request. In mediator when one object changes all others are notified!

Pitfalls
- Mediator becomes a central control object. As complexity of interaction grows,
mediator complexity can quickly get out of hand.
- Making a reusable mediator, one which can be used with multiple sets of different
objects is quite difficult. They are typically very specific to the collaboration.
Another competing pattern called Observer is much more reusable.
In—A—Hurry Summary
- When we want to decouple a group of objects which communicate with each other then we
can use the mediator design pattern.
- Each object only knows about the mediator object and notifies it about change in it’s
state. Mediator in turn will notify other objects on its behalf.
- Mediators are typically specific to a collaboration. It’s difficult to write a
reusable mediator. Observer design pattern solves this problem. However mediators are
easy to implement and extend.

Iterator pattern

What is Iterator?
- Iterator allows a way to access elements/children of an aggregate object in sequence
while hiding the actual internal data structure used.
- In Java language iterators are integral part of collection frameworks and they are
implementations of this design pattern.
- Iterators are stateful, meaning an iterator object remembers its position while
iterating.
- Iterators can become out of sync if the underlying collection is changed while a code
is using iterator.
Implement Iterator
- We start by defining Iterator interface
- Iterator has methods to check whether there is an element available in
sequence & to get that element
- We then implement the Iterator in a class. This is typically an inner class in our
concrete aggregate. Making it an inner class makes it easy to access internal data
structures
- Concrete iterator needs to maintain state to tell its position in collection of
aggregate. If the inner collection changes it can throw an exception to indicate
invalid state.
Implementation Considerations
- Detecting change to underlying data structure while some code is using an iterator is
important to notify to the client because then our iterator may not work correctly.
- Having our iterator implementation as inner class makes it easy to access internal
collection of aggregate objects.
Design Considerations
- Always prefer iterator interface so you can change the implementation without
affecting client.
- lterators have many applications where a collection is not directly used but we still
want to give a sequential access to information for example may be for reading lines
from file, from network.
Examples
- Yup! The iterator classes in Java’s collection framework are great examples of
iterator. © The concrete iterators are typically inner classes in each collection class
implementing java.util.lterator interface.
- The java.utiI.Scanner class is also an example of Iterator pattern. This class
supports InputStream as well and allows to iterate over a stream.

- The javax.xml.stream.XMLEventReader class is also an iterator. This class turns the


XML into a stream of event objects.
Pitfalls
- Access to index during iteration is not readily available like we have in a for loop.
- Making modifications to the collection while someone is using an iterator often makes
that iterator instance invalid as its state may not be valid.
In-a-hurry Summary
- When we want to iterate or give sequential access to elements of aggregate object we
can use iterator design pattern.
- Iterator needs access to internal data structure of aggregator to provide its
functionality. This usually means it’s quite common to have iterator implemented as
inner class.
- Iterator allows the client code to check whether there is an element available to
consume and give next available element.
- We can also provide reverse, or bi-directional (forward + backward) iterator
depending on underlying data structure.
Memento pattern

What is a Memento?
- When we want to store object’s state without exposing internal details about the
state then we can use memento design pattern.
- The main intent behind saving state is often because we want to restore the object to
a saved state.
- Using memento we can ask an object to give its state as a single, ”sealed” object &
store it for later use. This object should not expose the state for modification.
- This pattern is often combined with Command design pattern to provide undo
functionality in application
Implement Memento
- We start by finding originator state which is to be ”stored” in memento.
- We then implement the memento with requirement that it can’t be changed & @ outside
the originator.
- Originator provides a method to get its current snapshot out, which will return an
instance of memento.
- Another method in originator takes a memento object as argument and the originator
object resets itself to match with the state stored in memento.
Implementation Considerations
- It is important to keep an eye on the size of state stored in memento. A solution for
discarding older state may be needed to handle large memory consumption scenarios.
- Memento often ends up being an inner class due to the requirement that it must
encapsulate ALL details of what is stored in its instance.
- Resetting to previous state should consider effects on states of other
objects/services.
Design considerations
- If there is a definite, fixed way in which mementos are created then we can only
store incremental state in mementos. This is especially true if we are using command
design pattern where every command stores a memento before execution.
- Mementos can be stored internally by originator as well but this complicates the
originator. An external caretaker with fully encapsulated Memento provides you with
more flexibility in implementation.

Examples
- One great example of memento is the undo support provided by the
javax.swing.text.JTextComponent and its child classes like JTextField, JTextArea etc.
- The javax.swing.undo.UndoManager acts as the caretaker & implementations
ofjavax.swing.undo.UndoableEdit interface work as mementos. The
javax.swing.text.Document implementation which is model for text components in
swing is the originator.

- The java.io.Serializable is often given as an example of Memento but it is NOT a


memento & not even a design pattern. Memento object itself can be serialized but it is
NOT mandatory requirement of the pattern. In fact mementos work most of the times with
in-memory snapshots of state.

Pitfalls
- In practice creating a snapshot of state may not be easy if other objects are part of
originator’s state.
- Resetting a state may not be as simple as copying references. If state change of
originator is tied with other parts of application then those parts may become out of
sync/invalid due to resetting state.
In-A—Hurry Summary
- We can use memento design pattern to take a snapshot of object’s state which can be
then used to restore object to that particular state.
- Memento itself is created such that it doesn’t expose any state stored in it to any
other class aside from the originator.
- Originator provides a method to get a memento out of it. And another method to assign
it a memento, which results in getting the originator’s state reset to the one in
memento.
- Mementos need to be saved for them to be of any use. Originator can save them but it
adds complexity.
- Memento works well with command pattern. Each commands saves a memento as part of
execution.
Observer pattern

What IS Observer?
- Using observer design pattern we can notify multiple objects whenever an object
changes state.
- This design pattern is also called as publisher-subscriber or pub-sub.
- We are defining one-to-many dependency between objects, where many objects are
listening for state change of a single object, without tightly coupling all of them
together.
- This pattern is often implemented where listener only gets notification that
”something" has changed in the object’s state. Listeners query back to find out more
information if needed. This makes it more generic as different listeners may be
interested in different states.
Implementation
- We define an interface for observer. Observer is usually a very simple interface and
defines a method used by ”subject” to notify about state change.
- Subject can be an interface if we are expecting our observers to listen to multiple
objects or else subject can be any concrete class.
- Implementing subject means taking care of handling attach, detach of observers,
notifying all registered observers & providing methods to provide state information
requested by observers.
- Concrete observers use a reference passed to them to call ”subject” for getting more
information about the state. If we are passing changed state in notify method then this
is not required.
Implementation considerations
- In some rare scenarios you may end with a circular update loop. i.e. - an update to
observable’s state results in notification being sent to a observer which then takes
some action and that action results in state change of our observable, triggering
another notification and so on. Watch for these!
- An observer object can listen for changes in multiple subjects. It becomes quite easy
to identify originator for the notification if subjects pass a reference to themselves
in notification to observer.
- Performance can become an issue if number of observers are higher and if one or many
of them need noticeable time to process notification. This can also cause pile up of
pending notifications or missed notifications.
Design Considerations
- To reduce number of notifications sent on each state update, we can also have
observers register for a specific property or event. This improves performance as on an
event, subject notifies only the interested observers instead of all registered
observers.
- Typically notifications are sent by observable when someone changes its state, but we
can also make the client code, which is changing subject’s state, send notifications
too. This way we get notification when all state changes are done. However client code
get this additional responsibility which they may forget to carry out.
Examples
- Observer is such a useful pattern that Java comes with support for this support in
Java Class Library! We have java.util.0bserver interface & java.util.0bservable class
shipped with JDK.
-Although for some reason I haven’t seen developers using these outside of
Swing
- Another commonly used example is various listeners in Java Servlet application. We
can create various listeners by implementing interfaces like HttpSessionListener,
ServletRequestListener.
- We then register these listeners with ServletContext’s addListener method. These
listeners are notified when certain events occur like, creation of a request or
addition of a value to the session.
- The notification will be sent to observers based on the event that has taken place
and the interface(s) implemented by registered observers.
Pitfalls
- Every setter method triggering updates may be too much if we have client setting
properties one after another on our observable.
- Also each update becomes expensive as no. of observers increase and we have one or
more ”slow” observers in the list.
- If observers call back the subject to find what changed then this can add up to quite
a bit of overhead.
In-a-hurry summary
- Observer pattern allows us to define one-to-many dependency between objects where
many objects are interested in state change of a object.
- Observers register themselves with the subject which then notifies all registered
observers if any state change occurs.
- In the notification sent to observers it is common to only send reference of subject
instead of state values. Observers will call the subject back for more information if
needed.
- We can also register observers for a specific event only, resulting in improved
performance of sending notifications in the subject.
- This design pattern is also known as publisher-subscriber pattern. Java messaging
uses this pattern but instead of registering with subject, listeners register with a
JMS broker, which acts as a middleman.
State pattern

What is a State design pattern?


- State design pattern allows our objects to behave differently based on its current
internal state.
- This pattern allows to define the state specific behaviors in separate classes.
- Operations defined in the class delegate to the current state object’s implementation
of that behavior.
- State transitions can be triggered by states themselves in which case each state
knows about at least one other state’s existence.
- A benefit of this pattern is that new states and thus new behaviors can be added
without changing our main class.
Implement State pattern
- Identify distinct values for state of our object (context). Each state value will be
a separate class in our implementation. These classes will provide behavior specific to
the state value they represent.
- In our main/context class method implementations we’ll delegate the operation to
current state object.
- We have to decide how our state transition is going to happen. States can themselves
transition to next state based on input received in a method. Other option is context
itself can initiate transition.
- Client interacts with our main class or context and is unaware of existence of state.
Implementation considerations
- In some implementations clients themselves can configure context with initial state.
However after that the state transition is handled either by states or context.
- If state transitions are done by state object itself then it has to know about at
least one state. This adds to the amount of code change needed when adding new states.
Design considerations
- Using flyweight pattern we can share states which do not have any instance variables
and only encapsulate behaviour specific to that state.
- State design pattern is not same as a state machine. A state machine in loose terms
focuses on state transitions based on input values & using some table to map these
inputs to states. A state design pattern focuses on providing a behaviour specific to a
state value of context object.
Examples
- One of the examples of state pattern can be found in JSF(Java Server Faces)
framework’s LifeCycIe implementation.
- FacesServIet will invoke execute & render methods of LifeCycle. LifeCycle instance in
turn collaborates with multiple ”phases” to execute a JSF request. Here each phase
represents a state in state pattern.
- JSF has six phases: RestoreViewPhase, ApplyRequestValues, ProcessValidationsPhase,
UpdateModelValuesPhase, InvokeApplicationPhase, and RenderResponsePhase
- The LifeCycle also provides an object of FacesContext to these phases to help in
providing state specific behavior.
- In case you are not familiar with JSF, then you can always fall back on the order
processing example that we studied.
Pitfalls
- A lot more classes are created for providing functionality of context & all those
need unit testing as well.
- State transitions can be a bit tricky to implement. This becomes more complicated if
there multiple possible states to which object can transition from current state. And
if states are responsible for triggering transitions then we have a lot more coupling
between states.
- We may not realize all possible states we need at the beginning of our design. As our
design evolves we may need to add more states to handle a particular behavior.
In—A—Hurry Summary
- If we have an object whose behavior is completely tied to its internal state which
can be expressed as an object we can use the state pattern.
- Each possible state value now becomes a class providing behavior specific to a state
value.
- Our main object (aka context) delegates the actual operation to its current state.
States will implement behavior which is specific to a particular state value.
- Context object’s state change is explicit now, since we change the entire state
object.
- State transitions are handled either by states themselves or context can trigger
them.
Strategy pattern

What is a Strategy design pattern?


- Strategy pattern allows us to encapsulate an algorithm in a class. So now we can
configure our context or main object with an object of this class, to change the
algorithm used to perform given operation.
- This is really helpful if you have many possible variations of an algorithm.
- A good indication for applicability of strategy pattern is if we find different
algorithms/behaviors in our methods which are selected with conditional statements like
if-else or switch-case. |
- Strategy classes are usually implemented in an inheritance hierarchy so that we can
choose any one implementation and it’ll work with our main object/context as the
interface is same for all implementations.
Implementation
- We start by defining strategy interface which is used by our main/context class.
Context class provides strategy with all the data that it needs.
- We provide implementations for various algorithms by implementing strategy interface
a class per algorithm.
- Our context class provides a way to configure it with one of the strategy
implementations. Client code will create context with one of the strategy object.
Implementation ConsideratIons
- We can implement our context in a way where strategy object is optional. This makes
context usable for client codes who do not want to deal with concrete strategy objects.
- Strategy objects should be given all data they need as arguments to its method. If
number of arguments are high then we can pass strategy an interface reference which it
queries for data. Context object can implement this interface and pass itself to
strategy.
- Strategies typically end up being stateless objects making them perfect candidates
for sharing between context objects.
Design considerations
- Strategy implementations can make use of inheritance to factor out common parts of
algorithms in base classes making child implementations simpler.
- Since strategy objects often end up with no state of their own, we can use flyweight
pattern to share them between multiple context objects.
Examples
- The java.util.Comparator is a great example of strategy pattern. We can create
multiple implementations of comparator, each using a different algorithm to perform
comparison and supply those to various sort methods.
- Another example of strategy pattern is the ImplicitNamingStrategy &
PhysicalNamingStrategy contracts in Hibernate. Implementations of these classes are
used when mapping an Entity to database tables. These classes tell hibernate which
table to use & which columns to use.
- We can use different algorithms to perform mapping from domain model mapping to a
logical name via ImplicitNamingStrategy & then from logical name to physical name via
PhysicalNamingStrategy.

Pitfalls
- Since client code configures context object with appropriate strategy object, clients
know about all implementations of strategy. Introducing new algorithm means changing
client code as well.
In-A-Hurry Summary
- Strategy pattern allows us to encapsulate algorithms in separate classes. The class
using these algorithms (called context) can now be configured with desired
implementation of an algorithm.
- It is typically the responsibility of client code which is using our context object
to configure it.
- Strategy objects are given all data they need by the context object. We can pass data
either in form of arguments or pass on context object itself.
- Strategy objects typically end up being stateless making them great candidates for
flyweight pattern.
- Client code ends up knowing about all implementations of strategy since it has to
create their objects.
Template pattern

What is a Template Method?


- Using template method design pattern we define an algorithm in a method as a series
of steps (method calls) and provide a chance for subclasses to define or redefine some
of these steps.
- The pattern works by defining abstract methods which then have to be implemented by
concrete subclasses. These methods are like hooks which are then called by template
method.
- This pattern allows you to defer implementation of parts of your algorithm which can
vary or change.
- Template methods are an example of inversion of control principle — Don’t call us,
we’ll call you! And this is of course referring to the way template method calls other
methods implemented in subclass.
Implement Template Method
- We start by defining our algorithm in template method. We try to break algorithm in
multiple steps where each step will become an abstract method.
- While breaking down algorithm the number of steps should not be too many or it can
become quite tedious to implement all of them in subclasses.
- Next we implement the abstract steps in one or more subclasses.
Implementation Considerations
- A balance must be kept in how much granular we want to keep our steps. Too many steps
means too many methods to override for subclass where each one may be just a primitive
operation. Too few steps on the other hand would mean subclasses end up defining the
major parts of algorithm.
- If needed the template method can be made ?nal to prevent subclasses from changing
base algorithm.
Design Considerations
- We can use inheritance within subclasses to reuse parts from already implemented
steps. This approach allows subclasses to only change steps they need.
- Factory method design pattern uses template method. Actual factory method is often
called as part of another template method.
Examples of Template Method
- The java.uti|.AbstractMap, java.uti|.AbstractSet classes have many non-abstract
methods that are good exampels of template method pattern.

Pitfalls
- Tracking down what code executed as part of our algorithm requires looking up
multiple classes. The problem becomes more apparent if subclasses themselves start
using inheritance themselves to reuse only some of the existing steps & customize a
few.
- Unit testing can become a little more difficult as the individual steps may require
some specific state values to be present.
In-A-Hurry Summary
- Template method allow us to define a skeleton of an algorithm in base class. Steps of
algorithm are defined as abstract methods in base class.
- Subclasses of our abstract class will provide implementation of steps. This way we
can have different implementations for same algorithm.
- Client will create object of any of the concrete subclasses and use the algorithm.
- Factory method design pattern is often implemented as part of template method design
pattern.
- One drawback of template method is algorithm implementation is now spread across
multiple classes so it makes it slightly difficult to understand.
Visitor pattern

What is visitor pattern?


- Visitor pattern allows us to define new operations that can be performed on an object
without changing the class definition of the object.
- Think of this pattern as an object (”visitor”) that visits all nodes in an object
structure. Each time our visitor visits a particular object from the object structure,
that object calls a specific method on visitor, passing itself as an argument.
- Each time we need a new operation we create a subclass of visitor, implement the
operation in that class and visit the object structure.
- Objects themselves only implement an ”accept” visit where the visitor is pass as an
argument. Objects know about the method in visitor created specifically for it and
invoke that method inside the accept method.
Implement Visitor Pattern
- We create visitor interface by defining ”visit” methods for each class we want to
support.
- The classes who want functionalities provided by visitor define ”accept” method which
accepts a visitor. These methods are defined using the visitor interface as parameter
type so that we can pass any class implementing the visitor to these methods.
- In the accept method implementation we’ll call a method on visitor which is defined
specifically for that class.
- Next we implement the visitor interface in one or more classes. Each implementation
provides a specific functionality for interested classes. If want another feature we
create new implementation of visitor.
Implementation considerations
- Visitor can work with objects of classes which do not have a common parent. So having
a common interface for those classes is optional. However the code which passes our
visitor to these objects must be aware of these individual classes.
- Often visitors need access to internal state of objects to carry out their work. So
we may have to expose the state using getters/setters.
Design Considerations
- One effect of this pattern is that related functionality is grouped in a single
visitor class instead of spread across multiple classes. So adding new functionality is
as simple as adding a new visitor class.
- Visitors can also accumulate state. 50 along with behavior we can also have state per
object in our visitor. We don’t have to add new state to objects for behavior defined
in visitor.
- Visitor can be used to add new functionality to object structure implemented using
composite or can be used for doing interpretation in interpreter design pattern.
Examples
- The dom4j library used for parsing XML has interface org.dom4j.Visitor &
implementation org.dom4j.VisitorSupport which are examples of visitor. By implementing
this visitor we can process each node in an XML tree.
- Another example of visitor pattern is the java.nio.?le.Fi|eVisitor & its
implementation SimpIeFileVisitor.

Pitfalls
- Often visitors need access to object’s state. So we end up exposing a lot of state
through getter methods, weakening the encapsulation.
- Supporting a new class in our visitors requires changes to all visitor
implementations.
- If the classes themselves change then all visitors have to change as well since they
have to work with changed class.
- A little bit confusing to understand and implement.
In-a-hurry Summary
- Visitor pattern allows to add new operations that work on objects without modifying
class definitions of these objects.
- Visitors define class specific methods which work with an object of that class to
provide new functionality.
- To use this pattern classes define a simple accept method which gets a reference to a
visitor and inside this method, objects class method on visitor which is defined for
that specific class.
- Adding a new functionality means creating a new visitor and implementing new
functionality in that class instead of modifying each class where this functionality is
needed.
- This pattern is often used where we have an object structure and then another class
or visitor itself iterates a over this structure passing our visitor object to each
object.
Null pattern

What is null object?


- We use ”null” value to represent an absence of object. Using "Null Object” pattern we
can provide an alternate representation to indicate an absence of object.
- Most important characteristic of a null object is that it’ll basically do nothing &
store nothing when an operation is called on it.
- Null object seems like a proxy as it stands in for a real object, however a proxy at
some point will use real object or transform to a real object & even in absence of the
real object proxy will provide some behavior with side effect. Null object will not do
any such thing. Null objects don’t transform into real objects.
- We use this pattern when we want to treat absence of a collaborator transparently
without null checks.
Implement Null Object
- We create a new class that represents our null object by extending from base class or
implementing given interface.
- In the null object implementation, for each method we’ll not do anything. However
doing nothing can mean different things in different implementations. E.g. If a method
in a null object returns something then we can either return another null object, a
predefined default value or null.
- Code which creates objects of our implementation will create & pass our null object
in a specific situation.
Implementation Considerations
- Class which is using Null Object should not have to do anything special when working
with this object.
- What ”do nothing” means for an operation can be different in different classes. This
is especially true where methods in null objects are expected to return values.
- If you find a need where your null object has to transform into a real object then
you better use something like state pattern with a null object as one of the states.
Design Considerations
- Since null objects don’t have a state 8: no complex behavior they are good candidates
for singleton pattern. We can use a single instance of null object everywhere.
- Null objects are useful in many other design patterns like state - to represent a
null state, in strategy pattern to provide a strategy where no action is taken on
input.
Examples
- The various adapter classes from java.awt.event package can be thought of as examples
null object. Only reason they are not the examples of this pattern is that they are
abstract classes but without any abstract method.
Pitfalls
- Creating a proper Null object may not be possible for all classes. Some classes may
be expected to cause a change, and absence of that change may cause other class
operations to fail.
- Finding what ”do nothing” means may not be easy or possible. If our null object
method is expected to return another object then this problem is more apparent.
In-A-Hurry Summary
- Null object pattern allows us to represent absence of real object as a do nothing
object.
- Method implementations in a Null object will not do anything. In case a return value
is expected, these methods will return a sensible, hard-coded default value.
- Classes which use Null object won’t be aware of presence of this special
implementation. Whole purpose of the pattern is to avoid null checks in other classes.
- Null objects do not transform into real objects, nor do they use indirection to real
objects.

You might also like