Structural Design Pattern
Structural Design Pattern
You start with an interface which creates a blue print for the class which will have decorators. Then
implement that interface with basic functionalities. Till now we have got an interface and an
implementation concrete class. Create an abstract class that contains (aggregation relationship) an
attribute type of the interface. The constructor of this class assigns the interface type instance to that
attribute. This class is the decorator base class. Now you can extend this class and create as many
concrete decorator classes. The concrete decorator class will add its own methods. After / before
executing its own method the concrete decorator will call the base instance’s method. Key to this
decorator design pattern is the binding of method and the base instance happens at runtime based on
the object passed as parameter to the constructor. Thus dynamically customizing the behaviour of that
specific instance alone.
The above is an interface depicting an icecream. Things are kept as simple as possible so that the
focus will be on understanding the design pattern. Following class is a concrete implementation of this
interface. This is the base class on which the decorators will be added.
@Override
public String makeIcecream() {
return "Base Icecream";
}
Following class is the decorator class. It is the core of the decorator design pattern. It contains an
attribute for the type of interface. Instance is assigned dynamically at the creation of decorator using
its constructor. Once assigned that instance method will be invoked.
Following two classes are similar. These are two decorators, concrete class implementing the abstract
decorator. When the decorator is created the base instance is passed using the constructor and is
assigned to the super class. In the makeIcecream method we call the base method followed by its
own method addNuts(). This addNuts() extends the behavior by adding its own steps.
Simple icecream has been created and decorated with nuts and on top of it with honey. We can use
as many decorators in any order we want. This excellent flexibility and changing the behaviour of an
instance of our choice at runtime is the main advantage of the decorator design pattern.
Output
Base Icecream + cruncy nuts + sweet honey
java.io.BufferedReader;
java.io.FileReader;
java.io.Reader;
The above readers of java API are designed using decorator design pattern.
Structural Design Patterns 4
using System;
interface IComponent {
string Operation();
}
class Component : IComponent {
public string Operation () {
return "I am walking ";
}
}
class DecoratorA: IComponent {
IComponent component;
Participants
The classes and/or objects participating in this pattern are:
• Component (LibraryItem)
o defines the interface for objects that can have responsibilities added to them
dynamically.
• ConcreteComponent (Book, Video)
o defines an object to which additional responsibilities can be attached.
• Decorator (Decorator)
o maintains a reference to a Component object and defines an interface that conforms
to Component's interface.
• ConcreteDecorator (Borrowable)
o adds responsibilities to the component.
// Decorator pattern -- Structural example
using System;
namespace DoFactory.GangOfFour.Decorator.Structural
{
/// <summary>
/// MainApp startup class for Structural
/// Decorator Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Create ConcreteComponent and two Decorators
ConcreteComponent c = new ConcreteComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();
// Link decorators
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();
// Wait for user
Console.ReadKey();} }
Structural Design Patterns 6
/// <summary>
/// The 'Component' abstract class
/// </summary>
abstract class Component
{
public abstract void Operation();
}
/// <summary>
/// The 'ConcreteComponent' class
/// </summary>
class ConcreteComponent : Component
{
public override void Operation()
{
Console.WriteLine("ConcreteComponent.Operation()");
} }
/// <summary>
/// The 'Decorator' abstract class
/// </summary>
abstract class Decorator : Component
{
protected Component component;
void AddedBehavior()
{
} }}
Output
ConcreteComponent.Operation()
ConcreteDecoratorA.Operation()
ConcreteDecoratorB.Operation()
Structural Design Patterns 7
This real-world code demonstrates the Decorator pattern in which 'borrowable' functionality is added
to existing library items (books and videos).
// Property
public int NumCopies
{
get { return _numCopies; }
set { _numCopies = value; }
}
// Constructor
public Video(string director, string title,
int numCopies, int playTime)
{
this._director = director;
this._title = title;
this.NumCopies = numCopies;
this._playTime = playTime;
}
public override void Display()
{
Console.WriteLine("\nVideo ----- ");
Console.WriteLine(" Director: {0}", _director);
Structural Design Patterns 8
// Constructor
public Decorator(LibraryItem libraryItem)
{
this.libraryItem = libraryItem;
}
// Constructor
public Borrowable(LibraryItem libraryItem)
: base(libraryItem)
{
}
Video -----
Director: Spielberg
Title: Jaws
# Copies: 23
Playtime: 92
Video -----
Director: Spielberg
Title: Jaws
# Copies: 21
Playtime: 92
borrower: Customer #1
borrower: Customer #2
Structural Design Patterns 9
Bridge design pattern is a modified version of the notion of “prefer composition over inheritance”.
When there are inheritance hierarchies creating concrete implementation, you lose flexibility because
of interdependence. Decouple implentation from interface and hiding implementation details from
client is the essense of bridge design pattern.
• Abstraction – core of the bridge design pattern and defines the crux. Contains a reference to
the implementer.
• Refined Abstraction – Extends the abstraction takes the finer detail one level below. Hides the
finer elements from implemetors.
• Implementer - This interface is the higer level than abstraction. Just defines the basic
operations.
• Concrete Implementation – Implements the above implementer by providing concrete
implementation.
@Override
public void manufacture() {
System.out.print("Car ");
workShop1.work();
workShop2.work();
}}
/**
* Refine abstraction 2 in bridge pattern */
public class Bike extends Vehicle {
@Override
public void manufacture() {
System.out.print("Bike ");
workShop1.work();
workShop2.work(); }}
Structural Design Patterns 11
/**
* Implementor for bridge pattern * */
public interface Workshop {
abstract public void work();
}
/**
* Concrete implementation 1 for bridge pattern * */
public class Produce implements Workshop {
@Override
public void work() {
System.out.print("Produced");
}}
/**
* Concrete implementation 2 for bridge pattern * */
public class Assemble implements Workshop {
@Override
public void work() {
System.out.println(" Assembled."); }}
/*
* Demonstration of bridge design pattern */
public class BridgePattern {
Output:
Car Produced Assembled.
Bike Produced Assembled.
Summary of Bridge Design Pattern
• 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.
• Should be used when we have need to switch implementation at runtime.
• Client should not be impacted if there is modification in implementation of abstraction.
• Best used when you have multiple implementations.
using System;
class BridgePattern {
// Bridge Pattern Judith Bishop Dec 2006, Aug 2007
// Shows an abstraction and two implementations proceeding independently
class Abstraction {
Bridge bridge;
public Abstraction (Bridge implementation) {
bridge = implementation;
}
public string Operation () {
return "Abstraction" +" <<< BRIDGE >>>> "+bridge.OperationImp();
}}
Structural Design Patterns 12
interface Bridge {
string OperationImp();
}
class ImplementationA : Bridge {
public string OperationImp () {
return "ImplementationA";
}}
class ImplementationB : Bridge {
public string OperationImp () {
return "ImplementationB";
}}
Participants
The classes and/or objects participating in this pattern are:
• Abstraction (BusinessObject)
o defines the abstraction's interface.
o maintains a reference to an object of type Implementor.
• RefinedAbstraction (CustomersBusinessObject)
o extends the interface defined by Abstraction.
• Implementor (DataObject)
o defines the interface for implementation classes. This interface doesn't have to
correspond exactly to Abstraction's interface; in fact the two interfaces can be quite
different. Typically the Implementation interface provides only primitive operations,
and Abstraction defines higher-level operations based on these primitives.
• ConcreteImplementor (CustomersDataObject)
o implements the Implementor interface and defines its concrete implementation.
Sample code in C#
This structural code demonstrates the Bridge pattern which separates (decouples) the interface from
its implementation. The implementation can evolve without changing clients which use the abstraction
of the object.
Structural Design Patterns 13
// Set ConcreteImplementor
customers.Data = new CustomersData();
customers.ShowAll();
// Wait for user
Console.ReadKey();
} }
/// The 'Abstraction' class
class CustomersBase {
private DataObject _dataObject;
protected string group;
public CustomersData()
{
// Loaded from a database
_customers.Add("Jim Jones");
_customers.Add("Samual Jackson");
_customers.Add("Allen Good");
_customers.Add("Ann Stills");
_customers.Add("Lisa Giolani"); }
Output
Jim Jones
Samual Jackson
Allen Good
------------------------
Customer Group: Chicago
Jim Jones
Samual Jackson
Allen Good
Ann Stills
Lisa Giolani
Henry Velasquez
------------------------
Structural Design Patterns 17
When a class with incompatible method needs to be used with another class you can use inheritance
to create an adapter class. The adapter class which is inherited will have new compatible methods.
Using those new methods from the adapter the core function of the base class will be accessed. This
is called “is-a” relationship. The same real world example is implemented using java as below. Dont
worry too much about logic, following example source code attempts to explain adapter design pattern
and the goal is simplicity.
The above implementation can also be done using composition. Instead of inheriting the base class
create adapter by having the base class as attribute inside the adapter. You can access all the
methods by having it as an attribute. This is nothing but “has-a” relationship. Following example
illustrates this approach. Difference is only in the adapter class and other two classes are same. In
most scenarios, prefer composition over inheritance. Using composition you can change the
behaviour of class easily if needed. It enables the usage of tools like dependency injection.
using System;
class Client {
How do we infer the above definition? Think of a component that solves a complex business
problem. That component may expose lot of interfaces to interact with it. To complete a
process flow we may have to interact with multiple interfaces.
To simplify that interaction process, we introduce facade layer. Facade exposes a simplified
interface (in this case a single interface to perform that multi-step process) and internally it
interacts with those components and gets the job done for you. It can be taken as one level of
abstraction over an existing layer.
Facade design pattern is one among the other design patterns that promote loose coupling. It
emphasizes one more important aspect of design which is abstraction. By hiding the
complexity behind it and exposing a simple interface it achieves abstraction.
In this scenario, oven provides you preprogrammed switches which can be considered as a
facade. On click on of a single switch the job gets done. That single menu switch works as an
abstraction layer between you and the internal components.These are realworld examples for
facade design pattern. In software scenario, you can have interfaces which acts as a facade.
Methods in these interfaces contains the interaction sequence, formatting and converting data
for input for components. As such it will not hold the business logic.
Structural Design Patterns 21
• just for the sake of introducing a facade layer developers tend to create
additional classes. Layered architecture is good but assess the need for
every layer. Just naming a class as ABCDFacade.java doesn’r really
make it a facade.
• Creating a java class and ‘forcing’ the UI to interact with other layers
through it and calling it a facade layer is one more popular mistake.
Facade layer should not be forced and its always optional. If the client
wishes to interact with components directly it should be allowed to
bypass the facade layer.
• Methods in facade layer has only one or two lines which calls the other
components. If facade is going to be so simple it invalidates its purpose
and clients can directly do that by themselves.
• A controller is not a facade.
• Facade is ‘not’ a layer that imposes security and hides important data
and implementation.
• Don’t create a facade layer in advance. If you feel that in future the
subsystem is going to evolve and become complicated to defend that do
not create a stub class and name it a facade. After the subsystem has
become complex you can implement the facade design pattern.
• Subsystems are not aware of facade and there should be no reference
for facade in subsystems.
Structural Design Patterns 22
/* Complex parts */
class CPU {
public void freeze() { ... }
public void jump(long position) { ... }
public void execute() { ... }
}
class Memory {
public void load(long position, byte[] data) { ... }
}
class HardDrive {
public byte[] read(long lba, int size) { ... }
}
/* Facade */
class ComputerFacade {
private CPU processor;
private Memory ram;
private HardDrive hd;
public ComputerFacade() {
this.processor = new CPU();
this.ram = new Memory();
this.hd = new HardDrive();
}
/* Client */
class You {
public static void main(String[] args) {
ComputerFacade computer = new ComputerFacade();
computer.start();
}
}
Face code in C#
class MainApp
{
public static void Main()
facade.MethodA();
facade.MethodB();
// "Subsystem ClassA"
class SubSystemOne
{
public void MethodOne()
// Subsystem ClassB"
class SubSystemTwo
{
public void MethodTwo()
// Subsystem ClassC"
class SubSystemThree
{
public void MethodThree()
// Subsystem ClassD"
class SubSystemFour
{
public void MethodFour()
Structural Design Patterns 24
// "Facade"
class Facade
{
SubSystemOne one;
SubSystemTwo two;
SubSystemThree three;
SubSystemFour four;
public Facade()
one.MethodOne();
two.MethodTwo();
four.MethodFour();
two.MethodTwo();
Structural Design Patterns 25
three.MethodThree();
MethodA() ----
SubSystemOne Method
SubSystemTwo Method
SubSystemFour Method
MethodB() ----
SubSystemTwo Method
SubSystemThree Method
Structural Design Patterns 26
Important Points
• Importance of composite pattern is, the group of objects should be treated similarly as a
single object.
• Manipulating a single object should be as similar to manipulating a group of objects. In sync
with our example, we join primitive blocks to create structures and similarly join structures to
create house.
• Recursive formation and tree structure for composite should be noted.
• Clients access the whole hierarchy through the components and they are not aware about if
they are dealing with leaf or composites.
1. The end nodes of the tree and will not have any child.
2. Defines the behaviour for single objects in the composition
Structural Design Patterns 27
Composite: (group)
import java.util.ArrayList;
import java.util.List;
structure2.add(block3);
structure.add(structure1);
structure.add(structure2);
structure.assemble();
}
}
--------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text; // for StringBuilder
namespace CompositePattern {
// The Interface
public interface IComponent <T> {
void Add(IComponent <T> c);
IComponent <T> Remove(T s);
string Display(int depth);
IComponent <T> Find(T s);
T Name {get; set;}
}
// The Composite
public class Composite <T> : IComponent <T> {
List <IComponent <T>> list = null;
(holder as Composite<T>).list.Remove(p);
return holder;
}
else
return this;
}
// The Component
public class Component <T> : IComponent <T> {
public T Name {get; set;}
Everything around us can be a candidate for part-whole hierarchy. Human body, a car, a computer,
lego structure, etc. A car is made up of engine, tyre, … Engine is made up of electrical components,
valves, … Electrical components is made up of chips, transistor, … Like this a component is part of a
whole system. This hierarchy can be represented as a tree structure using composite design pattern.
“Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat
individual objects and compositions of objects uniformly.” is the intent by GoF.
Important Points
• Importance of composite pattern is, the group of objects should be treated similarly as a
single object.
• Manipulating a single object should be as similar to manipulating a group of objects. In sync
with our example, we join primitive blocks to create structures and similarly join structures to
create house.
• Recursive formation and tree structure for composite should be noted.
• Clients access the whole hierarchy through the components and they are not aware about if
they are dealing with leaf or composites.
Structural Design Patterns 32
import java.util.ArrayList;
import java.util.List;
structure2.add(block3);
structure.add(structure1);
structure.add(structure2);
structure.assemble();
}}
Structural Design Patterns 33
participants
• Component (DrawingElement)
o declares the interface for objects in the composition.
o implements default behavior for the interface common to all classes, as appropriate.
o declares an interface for accessing and managing its child components.
o (optional) defines an interface for accessing a component's parent in the recursive
structure, and implements it if that's appropriate.
• Leaf (PrimitiveElement)
o represents leaf objects in the composition. A leaf has no children.
o defines behavior for primitive objects in the composition.
• Composite (CompositeElement)
o defines behavior for components having children.
o stores child components.
o implements child-related operations in the Component interface.
• Client (CompositeApp)
o manipulates objects in the composition through the Component interface.
Structural Design Patterns 34
using System;
using System.Collections.Generic;
namespace DoFactory.GangOfFour.Composite.Structural
class MainApp
root.Add(comp);
root.Add(leaf);
root.Remove(leaf);
root.Display(1);
Console.ReadKey();
}
Structural Design Patterns 35
/// <summary>
/// </summary>
// Constructor
this.name = name;
/// <summary>
/// </summary>
// Constructor
: base(name)
{ }
{ _children.Add(component); }
{ _children.Remove(component);}
Structural Design Patterns 36
component.Display(depth + 2);
/// <summary>
/// </summary>
// Constructor
: base(name)
{}
Output
-root
---Leaf A
---Leaf B
---Composite X
-----Leaf XA
-----Leaf XB
---Leaf C