1. Adapter Pattern
2. Composite Pattern
3. Proxy Pattern
4. Flyweight Pattern
5. Façade Pattern
6. Bridge Pattern
7. Decorator Pattern
Adapter
design pattern:
Adapter
design pattern is one of the structural design patterns that
makes two unrelated interfaces work together. Moreover, the object that joins
these unrelated interfaces is called an Adapter just like a mediator.
As a real-life example, we can think of a mobile charger as an adapter because
mobile battery needs 3 volts to charge, but the normal socket produces either
120V (in US) or 240V (in India). Therefore, the mobile charger works as an
adapter between mobile charging socket and the wall socket.
In the
adapter pattern, a wrapper class (i.e., the adapter) is used to translate
requests from it to another class (i.e., the adoptee). In effect, an adapter
provides particular interactions with an adoptee that are not offered directly
by the adoptee.
When to
use Adapter Pattern
The
Adapter pattern should be used when:
- There
is an existing class, and its interface does not match the one you need.
- You
want to create a reusable class that co-operates with unrelated or
unforeseen classes, that is, classes that don’t necessarily have
compatible interfaces.
- There are several existing subclasses to be used, but it’s impractical to adapt their interface by sub-classing each one. An object adapter can adapt the interface of its parent class.
Adapter
Pattern Example in JDK
- util.Arrays#asList()
- io.InputStreamReader(InputStream)
(returns a Reader)
- io.OutputStreamWriter(OutputStream) (returns a Writer)
Composite
Design Pattern
The
Composite Pattern allows you to compose objects into a tree structure to
represent the part-whole hierarchy. It means you can create a tree of objects
that is made of different parts, but that can be treated as a whole one big
thing. Composite lets clients treat individual objects and compositions
of objects uniformly, that’s the intent of the Composite Pattern.
In the
composite pattern, a tree structure exists where identical operations can be
performed on leaves and nodes. A node in a tree is a class that can have
children. A node class is a ‘composite’ class. A leaf in a tree is a
‘primitive’ class that does not have children. The children of a composite can
be leaves or other composites.
When to
use Composite Pattern
Below
is the conditions when we can use this pattern:
- When
we want to represent part-whole hierarchies of objects.
- When
we want clients to be able to ignore the difference between compositions
of objects and individual objects. Clients will treat all objects in the
composite structure uniformly.
Usage
in JDK
java.awt.Container#add (Component) is a great example of Composite pattern in java and used a lot in Swing.
Proxy
Design Pattern
The Proxy
Design Pattern provides a surrogate or placeholder for another object to
control access to it. In fact, the Proxy Pattern is used to create a
representative object that controls access to another object. It may be remote,
expensive to create or in need of being secured.
In the
Proxy Design Pattern, a client does not directly talk to the original object,
it delegates calls to the proxy object which calls the methods of the original
object. Moreover, the important point is that the client does not know about
the proxy.
When to
use the Proxy Pattern
Proxy is
applicable whenever there is a need for a more versatile or sophisticated
reference to an object than a simple pointer. Here are several common
situations in which the Proxy pattern is applicable:
- A
remote proxy provides a local representative for an object in a different
address space.
- A
virtual proxy creates expensive objects on demand.
- A
protection proxy controls access to the original object. Protection
proxies are useful when objects should have different access rights.
Proxy
Pattern in JDK
The
following cases are examples of usage of the Proxy Pattern in the JDK.
- lang.reflect.Proxy
- rmi.* (whole package)
Flyweight
Design Pattern
In the
flyweight pattern, instead of creating large numbers of similar objects, we
re-use objects. We can use it to reduce memory requirements and instantiation
time and related costs.
Before we
apply the flyweight design pattern, we need to consider the following factors:
- If
the number of Objects required in the application are huge in amount.
- Also, if the object creation is heavy on memory and it can also be time consuming.
When to
Use
Flyweight
design pattern facilitates us when we need to create a lot of Objects of a
class. Since every object consumes memory space, it can play a crucial role for
low memory devices, such as mobile devices or embedded systems. Moreover, we
can apply flyweight design pattern in order to reduce the load on memory with
the help of object’s sharing.
Flyweight
Pattern Example in JDK
All the wrapper classes valueOf () method uses cached objects showing use of Flyweight design pattern. The best example is Java String class String Pool implementation.
Facade
Design Pattern
The Facade
Design Pattern is a structural design pattern. In the facade pattern, facade
classes are used to provide a single interface to set of classes. The facade
simplifies a client’s interaction with a complex system by localizing the
interactions into a single interface. As a result, the client can interact with
a single object rather than being required to interact directly in complicated
ways with the objects that make up the subsystem.
According to GoF: ‘Provide a unified interface to a set of interfaces in a subsystem. Facade Pattern defines a higher-level interface that makes the subsystem easier to use’.
When to
use
- Facade
pattern is more like a helper for client applications; it doesn’t hide
subsystem interfaces from the client. Whether to use Facade or not is
completely dependent on client code.
- Facade
pattern can be applied at any point of development, usually when the
number of interfaces grows and system gets complex.
- Subsystem
interfaces are not aware of Facade and they shouldn’t have any reference
of the Facade interface.
- A
facade pattern should be applied for similar kind of interfaces; its
purpose is to provide a single interface rather than multiple interfaces
that does the similar kind of jobs.
- The
subsystem may be depended with one another. In such case, facade can act
as a coordinator and decouple the dependencies between the subsystems.
- We
can use the Factory pattern with Facade to provide a better interface to
client systems.
Usage
in Java
In
javax.faces.context, ExternalContext internally uses
ServletContext, HttpSession, HttpServletRequest, HttpServletResponse, etc. It
allows the Faces API to be unaware of the nature of its containing application
environment.
Bridge
Design Pattern
When we
have interface hierarchies in both interfaces as well as implementations, then
the BRIDGE design pattern is used to decouple the interfaces from
implementation and hiding the implementation details from the client programs.
According
to the GoF bridge design pattern is: Decouple an abstraction from
its implementation so that the two can vary independently.
The Bridge
Pattern’s intent is to put the abstraction and implementation into two
different class hierarchies so that both can be extend independently.
Adapter
Pattern vs Bridge Pattern
The Adapter
Design Pattern helps it two incompatible classes to work together.
But the Bridge Design Pattern decouples the abstraction and
implementation by creating two different hierarchies
When to
Use and other points
- Should
be used when we have a need to switch implementation at runtime.
- The
client should not be impacted if there is a modification in implementation
of abstraction.
- Best
used when you have multiple implementations.
- Creates
two different hierarchies. One for abstraction and another for
implementation.
- Avoids
permanent binding by removing the dependency between abstraction and
implementation.
- We
create a bridge that coordinates between abstraction and implementation.
- Abstraction
and implementation can be extended separately.
Usage
in JDK
- AWT
(It provides an abstraction layer which maps onto the native OS the
windowing support.)
- JDBC
Decorator
Design Pattern
The
primary intent of the Decorator Design Pattern is to attach additional
responsibilities to an object dynamically. Decorators provide a flexible
alternative to sub-classing for extending functionality.
The
Decorator Pattern facilitates us when we need to extend the functionality of an
object dynamically without having to change the original class source or using
inheritance. This is accomplished by creating an object wrapper referred to as
a Decorator around the actual object.
When to
use the Decorator Design Pattern
Use
the Decorator pattern in the following cases:
- To
add responsibilities to individual objects dynamically and transparently,
that is, without affecting other objects.
- For
responsibilities that can be withdrawn.
- When
extension by sub-classing is impractical. Sometimes a large number of
independent extensions are possible and would produce an explosion of
subclasses to support every combination. Or a class definition may be
hidden or otherwise unavailable for sub-classing.
- It’s
easy to maintain and extend when the number of choices are more.
Usage
in Java
We
use the decorator pattern mostly in Java IO classes, such as FileReader,
BufferedReader etc.
- The
disadvantage of decorator pattern is that it uses a lot of similar kind of
objects (decorators).
No comments:
Post a Comment