The Concept of Structural Design Patterns
The Concept of Structural Design Patterns
1
6/9/2023
The Gang of Four has described seven such structural ways or patterns
1. Adapter Pattern Adapting an interface into another according to client expectation.
2. Bridge Pattern Separating abstraction (interface) from implementation.
3. Composite Pattern Allowing clients to operate on hierarchy of objects.
4. Decorator Pattern Adding functionality to an object dynamically.
5. Facade Pattern Providing an interface to a set of interfaces.
6. Flyweight Pattern Reusing an object by sharing it.
7. Proxy Pattern Representing another object.
ADAPTER PATTERN
Ever tried to use your camera memory card in your laptop. You cannot use it directly simply because there is
no port in laptop which accept it. You must use a compatible card reader. You put your memory card into the
card reader and then inject the card reader into the laptop. This card reader can be called the adapter.
A similar example is your mobile charger or your laptop charger which can be used with any power supply
without fear of the variance power supply in different locations. That is also called power “adapter”.
In programming as well, adapter pattern is used for similar purposes. It enables two incompatible interfaces
to work smoothly with each other.
Every day millions of lines of code is written. Most of the code is rewritten. Many a times there is a small change in
requirement and old code doesn’t fit. What if we adapt the code so that it becomes reusable? Adapter design
pattern in java helps to reuse the existing code even if it is incompatible.
2
6/9/2023
CONCEPT
Adapter Pattern acts as an intermediary to convert an otherwise incompatible interface to one that a client
expects.
This is useful in cases where we want to take an existing class whose source code cannot be modified and
make it work with another class.
The Adapter Pattern is also known as Wrapper. Wrap an existing class with a new interface.
When an outside component provides captivating functionality that we'd like to reuse, but it's
incompatible with our current application. A suitable Adapter can be developed to make them
compatible with each other
When our application is not compatible with the interface that our client is expecting
When we want to reuse legacy code in our application without making any modification in the
original code
3
6/9/2023
Client collaborates with objects conforming to the Target interface. This class will interact with the Adapter
class.
Adaptee defines an existing interface that needs adapting. This is the class which is used by the Adapter
class to reuse the existing functionality and modify them for desired use.
Adapter adapts the interface of Adaptee to the Target interface. This class is a wrapper class which
implements the desired target interface and modifies the specific request available from the Adaptee class.
HOW TO IMPLEMENT
Identify the players: the component(s) that want to be accommodated (i.e. the client), and the
component that needs to adapt (i.e. the adaptee).
Identify the interface that the client requires.
Design a "wrapper" class that can "impedance match" the adaptee to the client.
The adapter/wrapper class "maps" the client interface to the adaptee interface.
4
6/9/2023
EXAMPLE:
In this example, we can calculate the area of a rectangle easily using the Calculator class and its
getArea() method that uses a rectangle as an input .
Now suppose we want to calculate the area of a triangle, but we need to get the area of the triangle
through the getArea() method of Calculator. How can we do that?
To do that we have made a CalculatorAdapter for the triangle and passed a triangle in its getArea()
method.
The method will translate the triangle input to rectangle input and in turn, it will call the getArea() of
Calculator to get the area of it.
From the user’s point of view, it seems to the user that he is passing a triangle to get the area of that
triangle.
ADAPTEE ADAPTER
5
6/9/2023
TARGET
CLIENT
6
6/9/2023
PARTICIPANTS:
AdapterPattern
Triangle Calculator
CalculatorAdapter
There are some standard Adapters in Java core libraries such as:
java.util.Arrays#asList() :This method accepts multiple strings and return a list of input strings. Though it’s very basic
usage, but it’s what an adapter does, right?
java.io.InputStreamReader(InputStream) (returns a Reader object)
7
6/9/2023
Cons
Performance affected due to extra processes
All the processes communicate through adapters only
BRIDGE PATTERN
Bridge is a structural design pattern that lets you split a large class or
a set of closely related classes into two separate hierarchies—
abstraction and implementation—which can be developed
independently of each other.
The format definition, directly from the GoF book, Design Patterns.
“Decouples an abstraction from its implementation so that the two can vary
independently.”
8
6/9/2023
As shown in image, we have 4 different If we implement bridge pattern then we just need 1
chargers. 2 for house use and 2 for Car use. adapter each for house and for car use.
Similarly, in case of software development there are so many cases, where we need separate things to
make more reusable code. In such cases bridge design pattern is used to have communication between
the components.
THE CONCEPT
Let’s clarify this using the abstraction and concrete implementation strategies. Assume you have
two systems with abstract and concrete classes in each of the system. System X consists of
‘Abstract A’ and it’s concrete implementation ‘Concrete A’. Then, the System Y consists of ‘Abstract
B’ and it’s concrete implementation ‘Concrete B’. Abstract A connects with the Abstract B by a ‘Has-
A’ relationship. The Has-A relationship is achieved through composition where the abstraction
maintains a reference of the implementation and forwards client requests to it. .Abstract A
maintains an instance of Abstract B within itself. This ‘Has-A’ relationship makes a bridge between
the two systems. Hence, the pattern contains two layers of abstraction. Thus, the pattern was called
as the bridge pattern.
9
6/9/2023
WHERE TO USE
When you want to separate the abstract structure and its concrete implementation.
When you want to hide implementation details from clients. Changes in implementation should have no impact
on clients.
If any function is doing multiple things
We can separate into two functions
RefinedAbstraction
Implementer
10
6/9/2023
EXAMPLE
Say you have a geometric Shape class with a pair of subclasses: Circle and Square. You want to extend this class
hierarchy to incorporate colors, so you plan to create Red and Blue shape subclasses. However, since you already
have two subclasses, you’ll need to create four class combinations such as BlueCircle and RedSquare.
Adding new shape types and colors to the hierarchy will grow
it exponentially. For example, to add a triangle shape you’d
need to introduce two subclasses, one for each color. And
after that, adding a new color would require creating three
subclasses, one for each shape type. The further we go, the
worse it becomes.
This problem occurs because we’re trying to extend the shape classes in two independent dimensions: by form and
by color. That’s a very common issue with class inheritance.
The Bridge pattern attempts to solve this problem by switching from inheritance to the object composition. What this
means is that you extract one of the dimensions into a separate class hierarchy, so that the original classes will
reference an object of the new hierarchy, instead of having all of its state and behaviors within one class.
11
6/9/2023
EXAMPLE CONT…
BlueColor
Circle Square
BlueColor()
ABSTRACTION
12
6/9/2023
REFINED ABSTRACTION
IMPLEMENTER
13
6/9/2023
CONCRETE IMPLEMENTER
CLIENT
Output:
14
6/9/2023
PARTICIPANTS:
BridgePatternEx
Shape IColor
Pros
Increases code re-usability
Reduces the duplicate code
Increases code maintainability
if we need to change something, change at one place only
15
6/9/2023
QUESTIONS!
16