Click to edit Master subtitle style
CHƯƠNG 6
STRUCTURAL PATTERNS
1
NỘI DUNG
Proxy Pattern
Decorator Pattern
Adapter Pattern
Façade Pattern
Flyweight Pattern
Composite Pattern
Bridge Pattern
2
PROXY PATTERN
Ths. Nguyễn Thanh Vũ 3
Proxy Pattern
Definition:
➢ Provide a surrogate or placeholder for another object
to control access to it
➢ A proxy is basically a substitute for an intended object.
When a client deals with a proxy object, it thinks that
it is dealing with the actual object. You need to
support this kind of design because dealing with an
original object is not always possible. This is because
of many factors such as security issues, for example.
So, in this pattern, you may want to use a class that
can perform as an interface to something else.
4
Proxy Pattern
Real-Life Example:
➢ In a classroom, when one student is absent, his best
friend may try to mimic his voice during roll call to try
to get the teacher to think his friend is there
5
Proxy Pattern
Computer World Example:
➢ An ATM implementation will hold proxy objects for
bank information that exists on a remote server. In the
real programming world, creating multiple instances
of a complex object (a heavy object) is costly in
general. So, whenever you can, you should create
multiple proxy objects that can point to the original
object. This mechanism can also help you to save the
computer/system memory.
6
Proxy Pattern
Class Diagram:
7
Proxy Pattern
public abstract class Subject
{
public abstract void DoSomeWork();
}
8
Proxy Pattern
public class ConcreteSubject : Subject
{
public override void DoSomeWork()
{
[Link]("[Link]()");
}
}
9
Proxy Pattern
public class Proxy : Subject
{
Subject cs;
public override void DoSomeWork()
{
[Link]("Proxy call happening
now...");
//Lazy initialization:We'll not instantiate
until the method is called
if (cs == null)
{
cs = new ConcreteSubject();
}
[Link]();
}
}
10
Proxy Pattern
class Program
{
static void Main(string[] args)
{
[Link]("***Proxy Pattern Demo***\n");
Proxy px = new Proxy();
[Link]();
[Link]();
}
}
11
Proxy Pattern
Exercise:
12
DECORATOR PATTERN
Ths. Nguyễn Thanh Vũ 13
Decorator Pattern
Definition:
➢ Attach additional responsibilities to an object
dynamically. Decorators provide a flexible alternative
to subclassing for extending functionality
14
Decorator Pattern
Concept:
➢ This pattern promotes the concept that your class
should be closed for modification but open for
extension. In other words, you can add a functionality
without disturbing the existing functionalities. The
concept is useful when you want to add some special
functionality to a specific object instead of the whole
class. This pattern prefers object composition over
inheritance. Once you master this technique, you can
add new responsibilities to an object without affecting
the underlying classes.
15
Decorator Pattern
Real-Life Example:
➢ Suppose you own a single-story house and you decide
to build a second floor on top of it. Obviously, you
may not want to change the architecture of the
ground floor. But you may want to change the design
of the architecture for the newly added floor without
affecting the existing architecture
16
Decorator Pattern
Real-Life Example:
17
Decorator Pattern
Computer World Example:
➢ Suppose in a GUI-based toolkit you want to add some
border properties. You could do this with inheritance,
but that cannot be treated as an ultimate solution
because you do not have absolute control over
everything from the beginning. So, this technique is
static in nature. Decorators offer a flexible approach.
They promote the concept of dynamic choices.
18
Decorator Pattern
Class Diagram:
19
Decorator Pattern
abstract class Component
{
public abstract void MakeHouse();
}
20
Decorator Pattern
class ConcreteComponent : Component
{
public override void MakeHouse()
{
[Link]("Original House is complete.
It is closed for modification.");
}
}
21
Decorator Pattern
abstract class AbstractDecorator : Component
{
protected Component com ;
public void SetTheComponent(Component c)
{
com = c;
}
public override void MakeHouse()
{
if (com != null)
{
[Link]();//Delegating the task
}
}
22
Decorator Pattern
class ConcreteDecoratorEx1 : AbstractDecorator
{
public override void MakeHouse()
{
[Link]();
[Link]("***Using a decorator***");
//Decorating now.
AddFloor();
//You can put additional stuffs as per your need
}
private void AddFloor()
{
[Link]("I am making an additional
floor on top of it.");
}
}
23
Decorator Pattern
class ConcreteDecoratorEx2 : AbstractDecorator
{
public override void MakeHouse()
{
[Link]("");
[Link]();
[Link]("***Using another
decorator***");
//Decorating now.
PaintTheHouse();
//You can put additional stuffs as per your need
}
private void PaintTheHouse()
{
[Link]("Now I am painting the
house.");
}
}
24
Decorator Pattern
class Program
{
static void Main(string[] args)
{
[Link]("***Decorator pattern Demo***\n");
ConcreteComponent cc = new ConcreteComponent();
//ConcreteDecoratorEx1 decorator1 = new ConcreteDecoratorEx1();
AbstractDecorator decorator1 = new ConcreteDecoratorEx1();
[Link](cc);
[Link]();
//ConcreteDecoratorEx2 decorator2 = new ConcreteDecoratorEx2();
AbstractDecorator decorator2 = new ConcreteDecoratorEx2();
//Adding results from decorator1
[Link](decorator1);
[Link]();
[Link]();
}
}
25
Decorator Pattern
Exercise:
26
ADAPTER PATTERN
Ths. Nguyễn Thanh Vũ 27
Adapter Pattern
Definition:
➢ Convert the interface of a class into another interface
that clients expect. The Adapter pattern lets classes
work together that could not otherwise because of
incompatible interfaces
28
Adapter Pattern
Concept:
➢ The core concept is best described by the following
examples
29
Adapter Pattern
Real-Life Example:
➢ A common use of this pattern is when you use an
electrical outlet adapter/AC power adapter in
international travels. These adapters can act as
middlemen so that an electronic device, say a laptop
that accepts a U.S. power supply, can be plugged into
a European power outlet.
30
Adapter Pattern
Computer World Example:
➢ Suppose you have an application that can be broadly classified into two
parts: the user interface (UI or front end) and the database (back end).
Through the user interface, clients can pass some specific type of data or
objects. Your database is compatible with those objects and can store them
smoothly. Over a period of time, you may feel that you need to upgrade
your software to make your clients happy. So, you may want to allow some
other type of object also to pass through the UI. But in this case, the first
resistance will come from your database because it cannot store these new
types of objects. In such a situation, you can use an adapter that will take
care of the conversion of these new objects to a compatible form that your
old database can accept.
31
Adapter Pattern
Class Diagram:
32
Adapter Pattern
class Rect
{
public double length;
public double width;
}
class Calculator
{
public double GetArea(Rect rect)
{
return [Link] * [Link];
}
}
33
Adapter Pattern
class Triangle
{
public double baseT;//base
public double height;//height
public Triangle(int b, int h)
{
[Link] = b;
[Link] = h;
}
}
34
Adapter Pattern
class CalculatorAdapter
{
public double GetArea(Triangle triangle)
{
Calculator c = new Calculator();
Rect rect = new Rect();
//Area of Triangle=0.5*base*height
[Link] = [Link];
[Link] = 0.5 * [Link];
return [Link](rect);
}
}
35
Adapter Pattern
class Program
{
static void Main(string[] args)
{
[Link]("***Adapter Pattern
Demo***\n");
CalculatorAdapter cal = new CalculatorAdapter();
Triangle t = new Triangle(20, 10);
[Link]("Area of Triangle is " +
[Link](t) + " Square unit");
[Link]();
}
}
36
Adapter Pattern
Exercise:
37
FACADE PATTERN
Ths. Nguyễn Thanh Vũ 38
Facade Pattern
Definition:
➢ Provide a unified interface to a set of interfaces in a
subsystem. Facade defines a higher-level interface
that makes the subsystem easier to use
39
Facade Pattern
Concept:
➢ This pattern supports loose coupling. With this
pattern, you can emphasize the abstraction and hide
the complex details by exposing a simple interface
40
Facade Pattern
Real-Life Example:
➢ Suppose you are going to host a birthday party with
300 guests. Nowadays you can hire a party organizer
and let them know the key information such as the
party type, date and time of the party, number of
attendees, and so on. The organizer will do the rest
for you. You do not need to think about how they will
decorate the party room, whether the food will be
buffet style, and so on
41
Facade Pattern
Computer World Example:
➢ Think about a case when you use a method from a
library (in the context of a programming language).
You don’t care how the method is implemented in the
library. You just call the method for its easy usage
42
Facade Pattern
Class Diagram:
43
Facade Pattern
public class RobotBody
{
public void CreateHands()
{
[Link](" Hands manufactured");
}
public void CreateRemainingParts()
{
[Link](" Remaining parts (other than hands) are
created");
}
public void DestroyHands()
{
[Link](" The robot's hands are destroyed");
}
public void DestroyRemainingParts()
{
[Link](" The robot's remaining parts are destroyed");
}
}
44
Facade Pattern
public class RobotColor
{
public void SetDefaultColor()
{
[Link](" This is steel color
robot.");
}
public void SetGreenColor()
{
[Link](" This is a green color
robot.");
}
}
45
Facade Pattern
public class RobotHands
{
public void SetMilanoHands()
{
[Link](" The robot will have EH1 Milano hands");
}
public void SetRobonautHands()
{
[Link](" The robot will have Robonaut hands");
}
public void ResetMilanoHands()
{
[Link](" EH1 Milano hands are about to be
destroyed");
}
public void ResetRobonautHands()
{
[Link](" Robonaut hands are about to be destroyed");
}
}
46
Facade Pattern
public class RobotFacade
{
RobotColor rc;
RobotHands rh ;
RobotBody rb;
public RobotFacade()
{
rc = new RobotColor();
rh = new RobotHands();
rb = new RobotBody();
}
…
47
Facade Pattern
public void ConstructMilanoRobot()
{
[Link]("Creation of a Milano Robot Start");
[Link]();
[Link]();
[Link]();
[Link]();
[Link](" Milano Robot Creation End");
[Link]();
}
public void ConstructRobonautRobot()
{
[Link]("Initiating the creational process of a
Robonaut Robot");
[Link]();
[Link]();
[Link]();
[Link]();
[Link](" A Robonaut Robot is created");
[Link]();
}
48
Facade Pattern
public void DestroyMilanoRobot()
{
[Link](" Milano Robot's destruction process is
started");
[Link]();
[Link]();
[Link]();
[Link](" Milano Robot's destruction process is
over");
[Link]();
}
public void DestroyRobonautRobot()
{
[Link](" Initiating a Robonaut Robot's destruction
process.");
[Link]();
[Link]();
[Link]();
[Link](" A Robonaut Robot is destroyed");
[Link]();
}
49
Facade Pattern
class Program
{
static void Main(string[] args)
{
[Link]("***Facade Pattern
Demo***\n");
//Creating Robots
RobotFacade rf1 = new RobotFacade();
[Link]();
RobotFacade rf2 = new RobotFacade();
[Link]();
//Destroying robots
[Link]();
[Link]();
[Link]();
}
}
50
Facade Pattern
Exercise:
51
FLYWEIGHT PATTERN
Ths. Nguyễn Thanh Vũ 52
Flyweight Pattern
Definition:
➢ Use sharing to support large numbers of fine-grained
objects efficiently
53
Flyweight Pattern
Concept:
➢ A flyweight is an object. It tries to minimize memory
usage by sharing data as much as possible with other
similar objects. Shared objects may try to allow their
usage at fine granularities with minimum costs.
➢ Two common terms are used in the previous extract:
intrinsic and extrinsic. Intrinsic state is stored/shared
in the flyweight object. On the other hand, client
objects store the extrinsic state, and these objects are
passed to a flyweight object when they invoke the
operations.
54
Flyweight Pattern
Real-Life Example:
➢ Suppose you have a pen. You can use different ink
refills to write with different colors. So, the pen
without the refill can be considered the flyweight with
intrinsic data, and the refills can be considered the
extrinsic data in this example.
55
Flyweight Pattern
Computer World Example:
➢ This pattern helps you to save memory by reducing the number
of object instances at runtime. Suppose in a computer game
you have a large number of participants whose core structures
are the same, but their appearances vary (for example, they
may have different states, colors, weapons, and so on).
Therefore, if you want to store all of these objects with all
these variations/states, the memory requirement will be huge.
So, instead of storing all these objects, you can design the
application in such way that you will create one of these
instances, and your client object will maintain all of these
variations/states.
56
Flyweight Pattern
Class Diagram:
57
Flyweight Pattern
interface IRobot
{
void Print();
}
58
Flyweight Pattern
class SmallRobot : IRobot
{
public void Print()
{
[Link](" This is a small
Robot");
}
}
59
Flyweight Pattern
class LargeRobot : IRobot
{
public void Print()
{
[Link](" I am a large
Robot");
}
}
60
Flyweight Pattern
class RobotFactory
{
Dictionary<string, IRobot> shapes = new Dictionary<string, IRobot>();
public int TotalObjectsCreated
{
get { return [Link]; }
}
public IRobot GetRobotFromFactory(string robotType)
{
IRobot robotCategory = null;
if ([Link](robotType))
{
robotCategory = shapes[robotType];
}
else
{
switch (robotType)
{
case "Small":
robotCategory = new SmallRobot();
[Link]("Small", robotCategory);
break;
case "Large":
robotCategory = new LargeRobot();
[Link]("Large", robotCategory);
break;
default:
throw new Exception(" Robot Factory can create only small and large robots");
}
}
return robotCategory;
}
}
61
Flyweight Pattern
class Program
{
static void Main(string[] args)
{
[Link]("***Flyweight Pattern Demo***\n");
RobotFactory myfactory = new RobotFactory();
IRobot shape = [Link]("Small");
[Link]();
/*Now we are trying to get the 2 more Small robots.
Note that: now onwards we need not create additional small
robots because we have already created one of this category*/
for (int i = 0; i < 2; i++)
{
shape = [Link]("Small");
[Link]();
}
int NumOfDistinctRobots = [Link];
[Link]("\n Now, total numbers of distinct robot
objects is = {0}\n", NumOfDistinctRobots);
62
Flyweight Pattern
/*Here we are trying to get the 5 more Large robots.
Note that: now onwards we need not create additional small
robots because
we have already created one of this category */
for (int i = 0; i < 5; i++)
{
shape = [Link]("Large");
[Link]();
}
NumOfDistinctRobots = [Link];
[Link]("\n Distinct Robot objects created till now =
{0}", NumOfDistinctRobots);
[Link]();
}
}
63
Flyweight Pattern
Exercise:
64
COMPOSITE PATTERN
Ths. Nguyễn Thanh Vũ 65
Composite Pattern
Definition:
➢ Compose objects into tree structures to represent
part-whole hierarchies. Composite lets clients treat
individual objects and compositions of objects
uniformly.
66
Composite Pattern
Concept:
➢ This pattern is useful to represent part-whole
hierarchies of objects. In object-oriented
programming, a composite is an object with a
composition of one or more similar objects, where
each of these objects has similar functionality. (This is
also known as a “has-a” relationship among objects.)
So, the usage of this pattern is common in tree-
structured data. If you can apply the concept properly,
you do not need to discriminate between a branch
and the leaf nodes.
67
Composite Pattern
Real-Life Example:
➢ Think of an organization that consists of many
departments. In general, each of these departments
consists of multiple employees (in other words, all
these participants are basically employees in the
organization). Some employees are grouped together
to form a department, and those departments can be
further grouped together to build the whole
organization.
68
Composite Pattern
Computer World Example:
➢ I already mentioned that any tree data structure can follow this
concept. In that case, clients can treat the leaves of the tree
and the nonleaves (or, branches of the tree) in the same way
69
Composite Pattern
Class Diagram:
70
Composite Pattern
interface IEmployee
{
void PrintStructures();
}
71
Composite Pattern
class Employee : IEmployee
{
private string name;
private string dept;
// constructor
public Employee(string name, string dept)
{
[Link] = name;
[Link] = dept;
}
public void PrintStructures()
{
[Link]("\t\t"+[Link] + " works in " +
[Link]);
}
}
72
Composite Pattern
class CompositeEmployee : IEmployee
{
private string name;
private string dept;
//The container for child objects
private List<IEmployee> controls;
// constructor
public CompositeEmployee(string name, string dept)
{
[Link] = name;
[Link] = dept;
controls = new List<IEmployee>();
}
…
73
Composite Pattern
public void Add(IEmployee e)
{
[Link](e);
}
public void Remove(IEmployee e)
{
[Link](e);
}
public void PrintStructures()
{
[Link]("\t" + [Link] + " works in " + [Link]);
foreach (IEmployee e in controls)
{
[Link]();
}
}
}
74
Composite Pattern
class Program
{
static void Main(string[] args)
{
[Link]("***Composite Pattern Demo ***");
//Prinipal of the college
CompositeEmployee Principal = new
CompositeEmployee("[Link](Principal)","Planning-Supervising-Managing");
//The college has 2 Head of Departments-One from MAths, One from Computer
Sc.
CompositeEmployee hodMaths = new CompositeEmployee("[Link](HOD-
Maths)","Maths");
CompositeEmployee hodCompSc = new CompositeEmployee("Mr. [Link](HOD-CSE)",
"Computer Sc.");
//2 other teachers works in Mathematics department
Employee mathTeacher1 = new Employee("Math Teacher-1","Maths");
Employee mathTeacher2 = new Employee("Math Teacher-2","Maths");
//3 other teachers works in Computer Sc. department
Employee cseTeacher1 = new Employee("CSE Teacher-1","Computer Sc.");
Employee cseTeacher2 = new Employee("CSE Teacher-2", "Computer Sc.");
Employee cseTeacher3 = new Employee("CSE Teacher-3", "Computer Sc.");
75
Composite Pattern
//Teachers of Mathematics directly reports to HOD-Maths
[Link](mathTeacher1);
[Link](mathTeacher2);
//Teachers of Computer Sc directly reports to [Link]
[Link](cseTeacher1);
[Link](cseTeacher2);
[Link](cseTeacher3);
//Principal is on top of college
//HOD -Maths and Comp. Sc directly reports to him
[Link](hodMaths);
[Link](hodCompSc);
//Printing the leaf-nodes and branches in the same way.
//i.e. in each case, we are calling PrintStructures() method
[Link]("\n Testing the structure of a Principal object");
//Prints the complete structure
[Link]();
[Link]();
}
76
BRIDGE PATTERN
Ths. Nguyễn Thanh Vũ 77
Bridge Pattern
Definition:
➢ Decouple an abstraction from its implementation so
that the two can vary independently
78
Bridge Pattern
Concept:
➢ This pattern is also known as the Handle/Body
pattern. With it, you decouple an implementation
class from an abstract class by providing a bridge
between them. This bridge interface makes the
functionality of concrete classes independent from
the interface implementer classes. You can alter
different kinds of classes structurally without affecting
each other.
79
Bridge Pattern
Real-Life Example:
➢ In a software product development company, the development
team and the marketing team both play crucial roles. The
marketing team does a market survey and gathers the
customer requirements. The development team implements
those requirements in the product to fulfill the customer
needs.
➢ Any change (say, in the operational strategy) in one team
should not have a direct impact on the other team. In this case,
you can think of the marketing team as playing the role of the
bridge between the clients of the product and the
development team of the software organization
80
Bridge Pattern
Computer World Example:
➢ GUI frameworks can use the Bridge pattern to separate
abstractions from the platform- specific implementation. For
example, using this pattern, you can separate a window
abstraction from a window implementation for Linux or macOS.
81
Bridge Pattern
Class Diagram:
82
Bridge Pattern
//Implementor
public interface IState
{
void MoveState();
}
83
Bridge Pattern
//Implementor
//ConcreteImplementor-1
public class OnState : IState
{
public void MoveState()
{
[Link]("On State");
}
}
//ConcreteImplementor-2
public class OffState : IState
{
public void MoveState()
{
[Link]("Off State");
}
}
84
Bridge Pattern
//Abstraction
public abstract class ElectronicGoods
{
//Composition - implementor
protected IState state;
public IState State
{
get
{
return state;
}
set
{
state = value;
}
}
abstract public void MoveToCurrentState();
}
85
Bridge Pattern
//Refined Abstraction
public class Television : ElectronicGoods
{
//public Television(IState state) : base(state)
//{
//}
/*Implementation specific:
* We are delegating the implementation to the Implementor
object*/
public override void MoveToCurrentState()
{
[Link]("\n Television is functioning at : ");
[Link]();
}
}
86
Bridge Pattern
public class VCD : ElectronicGoods
{
//public VCD(IState state) : base(state)
//{
//}
/*Implementation specific:
* We are delegating the implementation to the Implementor
object*/
public override void MoveToCurrentState()
{
[Link]("\n VCD is functioning at : ");
[Link]();
}
}
87
Bridge Pattern
class Program
{
static void Main(string[] args)
{
[Link]("***Bridge Pattern Demo***");
[Link]("\n Dealing with a Television:");
ElectronicGoods eItem = new Television();
IState presentState = new OnState();
[Link] = presentState;
[Link]();
//Verifying Off state of the Television now
presentState = new OffState();
//eItem = new Television(presentState);
[Link] = presentState;
[Link]();
[Link]("\n \n Dealing with a VCD:");
presentState = new OnState();
//eItem = new VCD(presentState);
eItem = new VCD();
[Link] = presentState;
[Link]();
presentState = new OffState();
//eItem = new VCD(presentState);
[Link] = presentState;
[Link]();
[Link]();
}
}
88