0% found this document useful (0 votes)
48 views77 pages

Structural Design Patterns: Part-2

The document discusses the Bridge design pattern. The Bridge pattern decouples an abstraction from its implementation so that the two can vary independently. This allows adding or modifying abstractions and implementations without affecting each other. The document provides an example of shapes and colors to demonstrate how the Bridge pattern works and separates the abstraction and implementation hierarchies. It also discusses the components, advantages, and differences between Bridge and Adapter patterns.

Uploaded by

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

Structural Design Patterns: Part-2

The document discusses the Bridge design pattern. The Bridge pattern decouples an abstraction from its implementation so that the two can vary independently. This allows adding or modifying abstractions and implementations without affecting each other. The document provides an example of shapes and colors to demonstrate how the Bridge pattern works and separates the abstraction and implementation hierarchies. It also discusses the components, advantages, and differences between Bridge and Adapter patterns.

Uploaded by

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

Structural

Design Patterns
Chapter-3
Part-2
  Purpose
Creational Structural Behavioral

Interpreter
Class Factory Method Adapter Template Method

Adapter Chain of Responsibility


Scope Bridge Command
Iterator
Abstract Factory Composite Mediator
Builder
Object Prototype Decorator Memento
Observer
Singleton Façade State
Flyweight Strategy
Visitor
Proxy
Bridge Design Pattern
What is Bridge Design Pattern?
• This pattern focuses on a limitation in the

concept of abstraction.

• In the context of Java,

we use inheritance to develop the concept of

abstraction.
• Several implementation deviations support to
achieve the inheritance.
• However, this permanently binds the
implementation to the abstraction limiting the
flexibility.
• There can be situations when you want to
modify or extend the abstraction as well as the
implementations independently.
• Bridge pattern will help to resolve that limitation
by decoupling the abstraction from its
implementation.
• This pattern is a fine example of the concept of
‘Prefer composition over inheritance’
GOF definition for bridge design pattern,

“Decouples an abstraction from its

implementation so that the two can vary

independently.”
What is Abstraction?
• If we think of the point of Java language, abstraction
can be defined by an interface or by an abstract
class. It is a very narrow way to define the concept of
abstraction.
• When thinking as an object-oriented concept,
abstraction is just a representation or a
generalization to more complex detail.
• Abstraction covers the details of concrete
implementation of the whole thing.
• Normally, when an abstraction requires more

than one implementation inheritance is the

mechanism, which use to accommodate that

requirement. However, some scenarios require

adding or modifying abstraction as well as the

implementation independently without introducing

any errors to the system.


Real Life Examples
• Let’s assume a car and the remote control
scenario.
• The car is the abstraction for this scenario.
• Toyota, Honda and Audi will be the
implementations of the car abstraction. 
• Each car will have set of remotes controls.
• If the remote control is the abstraction
remote starter, remote door lock/open and
remote alarm will be the implementations of
the remote control.
• When there is one new addition to the car
implementation like BMW. It also should have the
3 implementations of the remote control.
Thus, abstractions and implementations can
vary according to the requirement.
How Bridge Pattern Works?
• In this pattern, usually, an abstract class
represents the abstraction.
• That abstraction maintains a separate
hierarchy.
• A separate hierarchy maintains the
implementation of the abstract class.
Structure of the Bridge Pattern
• 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.
• 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.
Solution to the Problem
• In an application,
• we should first identify the candidate
component to develop an abstraction and as
implementations.
• The abstraction and implementation are
separated into two hierarchies and
maintained independently.
Standard Technical Clarification for the Bridge
Pattern
• Figure 2 represents the UML diagram for the bridge
design pattern. It depicts the two sets of
abstractions, which vary independently.
Components of the Bridge Design Pattern
• Abstraction :This is one of the core
components of the bridge pattern and it includes
a reference to the implementor.
• Refined Abstraction – This extends the
abstraction and hides the finer elements from
implementor. That is this will not affect
implementor, as well as these implementations, does
not depend on any concrete implementors from the
Implementor interface.
• Implementor – This is the interface to the lower
level implementations. This does not need to
directly relate to the abstraction. It only connects
with a has-a relationship.
• Concrete Implementor – This component
implements the implementor interface by
defining an implementation. Implementation
details are hidden from the client.
Code Example
• Let us take a simple example to clarify this pattern.
• Assume one digital artist needs to create
shapes with different colours.
• He is developing a program to achieve this goal.
• Initially, there will be few options. However,
depending on the customer requirements there
will be different types shapes and variety of
colours can be accommodated to produce best
outcomes.
• Thus, the artist will have to add different
shapes to the ‘Shape’ category as well as
incorporate many colours to the ‘Color’ category
in the future.
• Before going further,

let us see what happens without the


bridge pattern.
Without the Bridge Pattern
• You will have to create long and complex
subclasses for each shape with difficult naming
patterns.
With the Bridge Pattern
• Two class hierarchies will allow more flexibility
between two class hierarchies.
• Let us put this scenario to the Java programming context.
Components of the Program
• AbstractShape : Represents the abstract class/interface of the
set of concrete shape implementations
• RefinedShapeCircle : Circle is one extension of the ‘Shape’
abstraction
• RefinedShapeTriangle : Triangle is another example of the
‘Shape’ abstraction
• ColorImplementor : This is the abstraction for the ‘Color’
category and part of implementation for the ‘Shape’ category.
• ConcreteColorRed : Red color extension of the ‘Color’
abstraction
• ConcreteColorGreen : Green color extension of the ‘Color’
abstraction
Java Code Samples
When to use the Bridge Pattern
• When there is a need to avoid the tight coupling
between an abstraction and implementation
• When there is a need for extending the
abstraction and the composite implementation
separately by subclasses.
• When there is a hierarchical propagation of
several categories of classes in the system.
Advantageous of Bridge Design Pattern
• Bridge patterns allows independent variation
between two abstract and implementor systems
• It avoids the client code binding to a certain
implementation
• Abstraction and implementation can be clearly
separated allowing easy future extension
• Provides a good solution for cross-platform
development.
• Well suited for testing with stubs in initial
development cycle.
Drawbacks of Bridge Design Pattern
• This pattern may cause complexity if the
number of extensible components increased
• Possible performance issues due to unclear
messaging.
Difference between Bridge & Adapter Pattern

• Adapter is used to eliminate the


incompatibility of an already defined and existing
two systems while bridge pattern used to address
any difficulties prior to developing the
systems.
Decorator Design Pattern
What is Decorator Design Pattern?
• Decorator pattern provides some kind of
decorational effect on the original object.
• That is, the pattern provides the ability to add
new features and behaviors to a base object
without altering its existing structure.
• That is there will be additional features added
to the original object.
• The component, which adds these additional
features is called as the ‘Decorator’.

• The ‘Decorator’ class in this pattern act as a


wrapper object which dynamically attaches
additional features to the original object at run-time.
GoF definition
• ‘Attach additional responsibilities to an object
dynamically. Decorators provide a flexible
alternative to sub-classing for extending
functionality’
• As in the definition, the main intent of decorator
pattern is to attach additional responsibilities
and features dynamically to an object.

• However, at the same time, other instances or


base class will not be affected by the new
dynamic change.
• Only the individual object will receive the new
modification.

• Since this pattern solves the dynamic feature


addition at run-time, it resolves the problem of the
complex sub-classing requirement when
extending base class functionality.
Real Life Example for Decorator Design Pattern
• It’s like adding cheese topping to a pizza or
adding walnut and chocolate source topping to
an ice-cream. You can add any kind of cheese or
sauce to the pizza just before serving to the customer,
yet base pizza remains unchanged. Likewise, you can
request walnut or cherries on a vanilla ice cream or
you can change the mind and ask to add only
chocolate topping and cherry sauce. Base vanilla ice
cream won’t change and you can have whatever
topping you like on the ice cream. If there are 20
people in the group, they can request 20 vanilla ice
creams with different toppings, nuts, and fruits on
time of serving.
What is Decorator Class?
• Decorator class is the component, which inserts
new options to the base object dynamically
without any modification to other objects.
• The ‘Decorator’ is an interface or an abstract
class in java programming.
• It provides a platform to implement additional
features and functionalities.
• Then several classes will take the ‘Decorator’ as the

base and implement the concrete additional

behaviors, which are requested by the original

object at run-time. Hence, ‘Decorator’ acts as a

wrapper object to the original object.


Example for Decorator Design Pattern
• Let’s take a juice bar which makes different
kinds of juices. Their most popular product is
the milkshake. There are many flavours of
milkshakes to select. Imagine three friends went there
and ordered a banana milkshake, peanut butter shake
and chocolate milkshake.
• We need to represent this scenario for the decorator
pattern implementation. If we study the scenario
further, we can identify that the base component is a
milk with sugar and salt. Then there are three kinds of
additional features attached to this milkshake on the
serving time or blending moment dynamically. Thus,
we can break our class structure as below,
1. MilkShake interface: This is the base component
interface for both the original object and decorator object
2. ConcreteMilkShake : This is the actual base milkshake
which use to make the customer required flavour of milkshake
3. MilkShakeDecorator: This is the abstract decorator for
the subsequent concrete decorator classes.
4. BananaMilkShake: This is one of the concrete implementation
of the decorator interface. This decorator class adds the banana
flavour decoration to the concrete milkshake. Banana is the
additional state or feature in this particular instance.
5. PeanutButterShake : Special decoration for this milkshake
instance is peanut butter
6. ChocolateMilkShake : Special decoration for this milkshake
instance is Chocolate
7. MilkShakeClient : The class which requests the specific
instance from the juice bar
Class  Diagram for the Example
• You can see the relevant code samples for above
scenario,
When to use Decorator Pattern
• When there are large number of different
combinations or options for an object and sub-
classing is not the optimal solution
• When only one-object needs, the additional
functionality applied from a group of similar
objects.
• When you want to change the object state and
behaviour at run-time.
Flyweight Design Pattern
Flyweight Design Pattern
• Sometimes, our applications hit slow
performances. This can be due to various reasons.
Instantiating many amounts of heavy objects
can be one of the very common reasons for the low
system performance.
• This can be rectified by the flyweight pattern
successfully. Flyweight pattern introduces a new
object called ‘Flyweight’ to avoid the creation of a
large number of heavy and high memory
consumption objects. This can be a kind of basic
caching mechanism to reduce the overhead.
GoF Definition
• Facilitates the reuse of many fine-grained
objects, making the utilization of large numbers of
objects more efficient.
• In this context, fine-grained objects are the objects
that consume large memory and heavy for the pool.
• Flyweight object act as the one shareable object.
Thus, that shareable object takes the place of a large
number of fine-grained objects efficiently.
• In this mechanism, the system requires to store only
the flyweight object by sharing common parts of
object state among multiple objects.
• Thus, RAM does not need to store all the other
similar heavy objects and can save huge
performance overhead.
What is Flyweight Object?
• This is the core component of the flyweight design
pattern. It provides the full solution for the problem
being addressed by this pattern. Flyweight is an
object that can be used in place of a number of
similar heavyweight objects and it efficiently
shares the common information present in the
similar object pool.
• It is important to note that flyweight objects are
immutable.
• That is they cannot be modified after the
construction occurred.
• This is to preserve the template nature of the
flyweight object in order to support the
duplication role. This is achieved via keeping the
state of the objects constant.
• Let’s briefly identify the state details of the
flyweight object.
Two States of Flyweight Design Pattern
• The main objective of the flyweight pattern is to
reduce the memory load by sharing objects.
• This is mainly achieved by separating the
object properties into two states.
• Each flyweight object can be divided into two
categories as state-independent and state-
dependent aka ‘Intrinsic’ and ‘Extrinsic’
respectively.
Intrinsic State
• This state contains data that are unchangeable
and independent of the context of the flyweight
object. Those data can be stored permanently
inside the flyweight object.
• This makes the flyweight object shareable.
The intrinsic data are stateless and generally
remains unchanged. This feature gives the ability to
replicate the flyweight object properties among
other similar objects. It’s important to note that
flyweight objects should receive their intrinsic state
only via constructor parameters not exposing setters
or public fields.
Extrinsic State
• This state contains the properties and data
applied or calculated on runtime.
• Thus, those data are not stored in the memory.
• Since the extrinsic state is context dependent and
variant, those objects cannot be shared.
• Therefore, the client objects are responsible for
passing the extrinsic state related data to the
flyweight object when needed. Extrinsic state data
can be passed to the flyweight object through
arguments.
Real World Examples of Flyweight Design
Pattern
• Alphabet characters of a text editor
• Let’s just focus on the alphabet characters for this
example. Text editors have 26 distinct letters to
write words. The editor has to instantiate all 26
letters repeatedly. For instance, when typing
‘Birthday Baby’, there are three occurrences of the
letter ‘b’. If instantiate three different characters ‘O’
objects separately it is a complete waste of time,
effort and memory because it is the same object
base.
• Only the extrinsic effect of letter ‘b’ has changed.
That is one occurrence it is bold-capital ‘b’ and next
it is just capital while the final is simple ‘b’.
• To overcome repeated heavy object creation, we can
use a flyweight object.
• Keeping the base of letter ‘b’ as intrinsic and
other styles as extrinsic data.
Class Diagram for Flyweight Design Pattern
Components of Flyweight Design Pattern
• Flyweight Interface
• This is the base interface for building concrete flyweight classes.
This interface contains a method, which takes the extrinsic data as
arguments. Thus, the implementing flyweights can receive and use
extrinsic data as required. Sometimes, this can be an abstract class.
• Flyweight Factory
• In this pattern, clients do not create Flyweight objects directly.
Instead, Flyweight Factory class creates and manages the
flyweight objects in the system. This is due to the existing
Flyweight object pool in the memory. When there is a request for a
Flyweight object, factory checks for an already created object in
the pool, if there is, the reference to that object is returned.  If there
is no existing object, the factory creates a new object adds it to the
pool and return to the client. It also supports the sharing of
Flyweight objects
• ConcreteFlyweight
• This is the most frequent implementation from the Flyweight
interface. This implementation must carry the capabilities of the
intrinsic state. That is data must be unchangeable and shareable.
Objects are stateless in this implementation. Thus, the same
ConcreteFlyweight object can be used in different contexts.
• UnsharedFlyweight
• This concrete implementation facilitates the option to create
Flyweight objects that are not shareable. In this options, Flyweight
objects can be stateful.
• Although the flyweight design pattern enables sharing of
information, it is possible to create instances of concrete flyweight
classes that are not shared. In these cases, the objects may be
stateful.
• Client
• Client requests a Flyweight object via the FlyweightFactory and uses
the returned object. It doesn’t know how the pattern works.
• Factory Method Pattern Usage inside Flyweight Design
Pattern
• As you can see in the class diagram, there is a
FlyweightFactory class in the pattern implementation. This is
to avoid the unnecessary heavy object creation from the
scratch. Pattern maintains an object pool to cater object
requests. The client will directly call the factory to get the
required object. Then, factory checks whether the required
object is in the object pool. If the object exists within the pool,
the factory will return it with the added features (extrinsic) on
the fly. If the requested object is not inside the pool, the
FlyweightFactory class will create a new intrinsic state object,
add it to the pool, and return to the client with the requested
extrinsic state. Each new instance should be created by the
FlyweightFactory since it is the place of management and
shareability happens with clients
Code Example
• Let’s assume a factory that manufactures teacups.
• There are about four types of teacups.
• They differ only by shape and colour.
• The ingredients and quality are the same.
• The factory manufactures around 1000 items in one
batch for one type of teacup.
• In this case, creating 4000 teacups from the scratch
is an inefficient task. Instead, we can use the
Flyweight pattern to save the time and effort. Let’s
see the suitable components for the teacups
example.
Teacup Base Abstract Class
• This class contains the base methods for creating a
teacup.
• Like adding initial moulding ingredients, mixing
formula and applying suitable temperature and time
for making the base mixture.
Teacup Factory
• This class performs the creation and management of
teacups and it’s repository. This is the main
component that decides whether to create a brand
new cup mould or use the existing template and use
for cup creation.
Concrete Teacup
• This class include the methods to create different
shape and colour teacups derived from the abstract
class.
Customer
• Any teacup type requester who wants to have all
types of teacups.
• Code Samples
When to use the Flyweight Design Pattern
• When an application uses a large number of
objects.
• When there is a repetitive creation of heavy
objects.
• When there are memory allocation issues in the
application.
• When the many groups of objects can be
replaced by a few shared objects.
Advantages of Flyweight Design Pattern
• Reduce memory usage by sharing heavy
objects.
• Improved data caching for higher response
time.
• Increased performance due to a lesser number
of heavy objects.
Other Related Patterns
• There are few other design patterns, which relates
and used by the flyweight pattern.
• Flyweight pattern directly uses the factory
pattern to instantiate the objects.
• Flyweight pattern is a bit similar to Singleton
pattern when thinking about the usage of one
object creation to represent a lot.
• It is identified that ‘State’ and ‘Strategy’ pattern
objects can be implemented as Flyweight objects.
• As a contrasting feature, Flyweight shows how to
create many small objects while the facade
pattern shows how to create a single object
represent an entire subsystem.
Thank You

You might also like