0% found this document useful (0 votes)
76 views34 pages

Structural Design Pattern

The Decorator design pattern allows behavior to be added to individual objects, dynamically, without affecting the behavior of other objects from the same class. Decorators provide a flexible alternative to subclassing for extending functionality. The pattern attaches additional responsibilities to an object dynamically by wrapping the object with decorator objects. This allows functionality to be added and removed at runtime.

Uploaded by

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

Structural Design Pattern

The Decorator design pattern allows behavior to be added to individual objects, dynamically, without affecting the behavior of other objects from the same class. Decorators provide a flexible alternative to subclassing for extending functionality. The pattern attaches additional responsibilities to an object dynamically by wrapping the object with decorator objects. This allows functionality to be added and removed at runtime.

Uploaded by

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

Structural Design Patterns 1

Decorator Design Pattern


To extend or modify the behaviour of ‘an instance’ at runtime decorator design pattern is used.
Inheritance is used to extend the abilities of ‘a class’. Unlike inheritance, you can choose any single
object of a class and modify its behaviour leaving the other instances unmodified. In implementing the
decorator pattern you construct a wrapper around an object by extending its behaviour. The wrapper
will do its job before or after and delegate the call to the wrapped instance.

Design of decorator 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.

Decorator Design Pattern – UML Diagram


Structural Design Patterns 2

Implementation of decorator pattern

Following given example is an implementation of decorator design pattern. Icecream is a classic


example for decorator design pattern. You create a basic icecream and then add toppings to it as you
prefer. The added toppings change the taste of the basic icecream. You can add as many topping as
you want. This sample scenario is implemented below.

public interface Icecream {


public String makeIcecream();
}

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.

public class SimpleIcecream implements Icecream {

@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.

abstract class IcecreamDecorator implements Icecream {

protected Icecream specialIcecream;

public IcecreamDecorator(Icecream specialIcecream) {


this.specialIcecream = specialIcecream;
}

public String makeIcecream() {


return specialIcecream.makeIcecream();
}
}

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.

public class NuttyDecorator extends IcecreamDecorator {

public NuttyDecorator(Icecream specialIcecream) {


super(specialIcecream);
}

public String makeIcecream() {


return specialIcecream.makeIcecream() + addNuts();
}

private String addNuts() {return " + cruncy nuts";}}


public class HoneyDecorator extends IcecreamDecorator {
Structural Design Patterns 3

public HoneyDecorator(Icecream specialIcecream) {


super(specialIcecream);
}

public String makeIcecream() {


return specialIcecream.makeIcecream() + addHoney();
}

private String addHoney() {


return " + sweet honey";
}
}

Execution of the decorator pattern

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.

public class TestDecorator {

public static void main(String args[]) {


Icecream icecream =
new HoneyDecorator(new NuttyDecorator(new SimpleIcecream()));
System.out.println(icecream.makeIcecream());
}

Output
Base Icecream + cruncy nuts + sweet honey

Decorator Design Pattern in java API

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;

// Shows two decorators and the output of various


// combinations of the decorators on the basic component

interface IComponent {
string Operation();
}
class Component : IComponent {
public string Operation () {
return "I am walking ";
}
}
class DecoratorA: IComponent {
IComponent component;

public DecoratorA (IComponent c) {


component = c;
}

public string Operation() {


string s = component.Operation();
s += "and listening to Classic FM ";
return s;
}
}
class DecoratorB : IComponent {
IComponent component;
public string addedState = "past the Coffee Shop ";

public DecoratorB (IComponent c) {


component = c;
}

public string Operation () {


string s = component.Operation ();
s += "to school ";
return s;
}

public string AddedBehavior() {


return "and I bought a cappucino ";
}
}
class Client {

static void Display(string s, IComponent c) {


Console.WriteLine(s+ c.Operation());
}

static void Main() {


Console.WriteLine("Decorator Pattern\n");

IComponent component = new Component();


Display("1. Basic component: ", component);
Display("2. A-decorated : ", new DecoratorA(component));
Display("3. B-decorated : ", new DecoratorB(component));
Display("4. B-A-decorated : ", new DecoratorB(
new DecoratorA(component)));
// Explicit DecoratorB
DecoratorB b = new DecoratorB(new Component());
Display("5. A-B-decorated : ", new DecoratorA(b));
//Invoking its added state and added behaviour
Console.WriteLine("\t\t\t"+ b.addedState + b.AddedBehavior());
}
}
Structural Design Patterns 5

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;

public void SetComponent(Component component)


{
this.component = component;
}

public override void Operation()


{
if (component != null)
{
component.Operation();
}
} }
/// <summary>
/// The 'ConcreteDecoratorA' class
/// </summary>
class ConcreteDecoratorA : Decorator
{
public override void Operation()
{
base.Operation();
Console.WriteLine("ConcreteDecoratorA.Operation()");
} }
/// <summary>
/// The 'ConcreteDecoratorB' class
/// </summary>
class ConcreteDecoratorB : Decorator
{
public override void Operation()
{
base.Operation();
AddedBehavior();
Console.WriteLine("ConcreteDecoratorB.Operation()");
}

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).

// Decorator pattern -- Real World example


using System;
using System.Collections.Generic;
namespace DoFactory.GangOfFour.Decorator.RealWorld
{
class MainApp
{static void Main(){
// Create book
Book book = new Book("Worley", "Inside ASP.NET", 10);
book.Display();
// Create video
Video video = new Video("Spielberg", "Jaws", 23, 92);
video.Display();
// Make video borrowable, then borrow and display
Console.WriteLine("\nMaking video borrowable:");
Borrowable borrowvideo = new Borrowable(video);
borrowvideo.BorrowItem("Customer #1");
borrowvideo.BorrowItem("Customer #2");
borrowvideo.Display();
// Wait for user
Console.ReadKey(); } }
abstract class LibraryItem
{
private int _numCopies;

// Property
public int NumCopies
{
get { return _numCopies; }
set { _numCopies = value; }
}

public abstract void Display(); }


class Book : LibraryItem
{
private string _author;
private string _title;
// Constructor
public Book(string author, string title, int numCopies)
{
this._author = author;
this._title = title;
this.NumCopies = numCopies;
}
public override void Display()
{
Console.WriteLine("\nBook ------ ");
Console.WriteLine(" Author: {0}", _author);
Console.WriteLine(" Title: {0}", _title);
Console.WriteLine(" # Copies: {0}", NumCopies); } }
class Video : LibraryItem
{
private string _director;
private string _title;
private int _playTime;

// 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

Console.WriteLine(" Title: {0}", _title);


Console.WriteLine(" # Copies: {0}", NumCopies);
Console.WriteLine(" Playtime: {0}\n", _playTime); } }
abstract class Decorator : LibraryItem
{
protected LibraryItem libraryItem;

// Constructor
public Decorator(LibraryItem libraryItem)
{
this.libraryItem = libraryItem;
}

public override void Display()


{
libraryItem.Display();
} }
class Borrowable : Decorator
{
protected List<string> borrowers = new List<string>();

// Constructor
public Borrowable(LibraryItem libraryItem)
: base(libraryItem)
{
}

public void BorrowItem(string name)


{
borrowers.Add(name);
libraryItem.NumCopies--;
}

public void ReturnItem(string name)


{
borrowers.Remove(name);
libraryItem.NumCopies++;
}

public override void Display()


{
base.Display();

foreach (string borrower in borrowers)


{
Console.WriteLine(" borrower: " + borrower);
} } }}
Output
Book ------
Author: Worley
Title: Inside ASP.NET
# Copies: 10

Video -----
Director: Spielberg
Title: Jaws
# Copies: 23
Playtime: 92

Making video borrowable:

Video -----
Director: Spielberg
Title: Jaws
# Copies: 21
Playtime: 92

borrower: Customer #1
borrower: Customer #2
Structural Design Patterns 9

Bridge Design Pattern


“Decouple an abstraction from its implementation so that the two can vary independently” is the intent
for bridge design pattern as stated by GoF.

Bridge design pattern is a modified version of the notion of “prefer composition over inheritance”.

Problem and Need for Bridge Design Pattern

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.

Elements 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.

Example for core elements of Bridge Design Pattern


Vehicle -> Abstraction
manufacture()
Car -> Refined Abstraction 1
manufacture()
Bike -> Refined Abstraction 2
manufacture()
Workshop -> Implementor
work()
Produce -> Concrete Implementation 1
work()
Assemble -> Concrete Implementation 2
work()
Generic UML Diagram for Bridge Design Pattern
Structural Design Patterns 10

Before Bridge Design Pattern After Bridge Design Pattern

Sample Java Code for Bridge Design Pattern


/**
* abstraction in bridge pattern * */
abstract class Vehicle {
protected Workshop workShop1;
protected Workshop workShop2;

protected Vehicle(Workshop workShop1, Workshop workShop2) {


this.workShop1 = workShop1;
this.workShop2 = workShop2;
}
abstract public void manufacture();}
/**
* Refine abstraction 1 in bridge pattern */
public class Car extends Vehicle {

public Car(Workshop workShop1, Workshop workShop2) {


super(workShop1, workShop2);
}

@Override
public void manufacture() {
System.out.print("Car ");
workShop1.work();
workShop2.work();

}}
/**
* Refine abstraction 2 in bridge pattern */
public class Bike extends Vehicle {

public Bike(Workshop workShop1, Workshop workShop2) {


super(workShop1, workShop2);
}

@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 {

public static void main(String[] args) {

Vehicle vehicle1 = new Car(new Produce(), new Assemble());


vehicle1.manufacture();
Vehicle vehicle2 = new Bike(new Produce(), new Assemble());
vehicle2.manufacture();
}}

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";
}}

static void Main () {


Console.WriteLine("Bridge Pattern\n");
Console.WriteLine(new Abstraction (new ImplementationA()).Operation());
Console.WriteLine(new Abstraction (new ImplementationB()).Operation());
}}

UML class diagram

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

// Bridge pattern -- Structural example


using System;
namespace DoFactory.GangOfFour.Bridge.Structural
{
/// MainApp startup class for Structural
/// Bridge Design Pattern.
class MainApp
{
/// Entry point into console application.
static void Main(){
Abstraction ab = new RefinedAbstraction();

// Set implementation and call


ab.Implementor = new ConcreteImplementorA();
ab.Operation();

// Change implemention and call


ab.Implementor = new ConcreteImplementorB();
ab.Operation();

// Wait for user


Console.ReadKey();
} }
/// The 'Abstraction' class
class Abstraction
{
protected Implementor implementor;
// Property
public Implementor Implementor
{
set { implementor = value; }
}

public virtual void Operation()


{
implementor.Operation();
} }
/// The 'Implementor' abstract class
abstract class Implementor
{
public abstract void Operation();
}
/// The 'RefinedAbstraction' class
class RefinedAbstraction : Abstraction
{
public override void Operation()
{
implementor.Operation();
} }
/// <summary>
/// The 'ConcreteImplementorA' class
/// </summary>
class ConcreteImplementorA : Implementor
{
public override void Operation()
{
Console.WriteLine("ConcreteImplementorA Operation");
} }
/// The 'ConcreteImplementorB' class
class ConcreteImplementorB : Implementor {
public override void Operation()
{ Console.WriteLine("ConcreteImplementorB Operation"); }}}
Output
ConcreteImplementorA Operation
ConcreteImplementorB Operation
This real-world code demonstrates the Bridge pattern in which a BusinessObject abstraction is
decoupled from the implementation in DataObject. The DataObject implementations can evolve
dynamically without changing any clients.
Structural Design Patterns 14

// Bridge pattern -- Real World example


using System;
using System.Collections.Generic;
namespace DoFactory.GangOfFour.Bridge.RealWorld
{
/// MainApp startup class for Real-World
/// Bridge Design Pattern.
class MainApp
{
/// Entry point into console application.
static void Main()
{
// Create RefinedAbstraction
Customers customers = new Customers("Chicago");

// Set ConcreteImplementor
customers.Data = new CustomersData();

// Exercise the bridge


customers.Show();
customers.Next();
customers.Show();
customers.Next();
customers.Show();
customers.Add("Henry Velasquez");

customers.ShowAll();
// Wait for user
Console.ReadKey();
} }
/// The 'Abstraction' class
class CustomersBase {
private DataObject _dataObject;
protected string group;

public CustomersBase(string group)


{ this.group = group; }
// Property
public DataObject Data
{ set { _dataObject = value; }
get { return _dataObject; } }

public virtual void Next()


{ _dataObject.NextRecord(); }

public virtual void Prior()


{ _dataObject.PriorRecord();}

public virtual void Add(string customer)


{ _dataObject.AddRecord(customer); }

public virtual void Delete(string customer)


{ _dataObject.DeleteRecord(customer); }

public virtual void Show()


{ _dataObject.ShowRecord(); }

public virtual void ShowAll() {


Console.WriteLine("Customer Group: " + group);
_dataObject.ShowAllRecords();
} }
/// The 'RefinedAbstraction' class
class Customers : CustomersBase
{
// Constructor
public Customers(string group)
: base(group)
{ }
Structural Design Patterns 15

public override void ShowAll()


{
// Add separator lines
Console.WriteLine();
Console.WriteLine("------------------------");
base.ShowAll();
Console.WriteLine("------------------------");
} }
/// The 'Implementor' abstract class
abstract class DataObject
{
public abstract void NextRecord();
public abstract void PriorRecord();
public abstract void AddRecord(string name);
public abstract void DeleteRecord(string name);
public abstract void ShowRecord();
public abstract void ShowAllRecords(); }
/// The 'ConcreteImplementor' class
class CustomersData : DataObject
{
private List<string> _customers = new List<string>();
private int _current = 0;

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"); }

public override void NextRecord()


{ if (_current <= _customers.Count - 1)
{ _current++; }}

public override void PriorRecord()


{ if (_current > 0)
{ _current--; }}

public override void AddRecord(string customer)


{ _customers.Add(customer); }

public override void DeleteRecord(string customer)


{ _customers.Remove(customer); }

public override void ShowRecord()


{ Console.WriteLine(_customers[_current]); }

public override void ShowAllRecords()


{
foreach (string customer in _customers)
{
Console.WriteLine(" " + customer); }}}}

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

Adapter Design Pattern


An adapter helps two incompatible interfaces to work together. This is the real world definition for an
adapter. Adapter design pattern is used when you want two different classes with incompatible
interfaces to work together. The name says it all. Interfaces may be incompatible but the inner
functionality should suit the need.

How to implement adapter design pattern?


Adapter design pattern can be implemented in two ways. One using the inheritance method and second
using the composition method. Just the implementation methodology is different but the purpose and
solution is same.

Adapter implementation using inheritance

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.

public class CylindricalSocket {


public String supply(String cylinStem1, String cylinStem1) {
System.out.println("Power power power...");
}
}

public class RectangularAdapter extends CylindricalSocket {


public String adapt(String rectaStem1, Sting rectaStem2) {
//some conversion logic
String cylinStem1 = rectaStem1;
String cylinStem2 = rectaStem2;
return supply(cylinStem1, cylinStem2);
}
}

public class RectangularPlug {


private String rectaStem1;
private String rectaStem2;
public getPower() {
RectangulrAdapter adapter = new RectangulrAdapter();
String power = adapter.adapt(rectaStem1, rectaStem2);
System.out.println(power);
}
}
Structural Design Patterns 18

Adapter implementation using composition

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.

public class CylindricalSocket {


public String supply(String cylinStem1, String cylinStem1) {
System.out.println("Power power power...");
}
}

public class RectangularAdapter {


private CylindricalSocket socket;

public String adapt(String rectaStem1, Sting rectaStem2) {


//some conversion logic
socket = new CylindricalSocket();
String cylinStem1 = rectaStem1;
String cylinStem2 = rectaStem2;
return socket.supply(cylinStem1, cylinStem2);
}
}

public class RectangularPlug {


private String rectaStem1;
private String rectaStem2;
public getPower() {
RectangulrAdapter adapter = new RectangulrAdapter();
String power = adapter.adapt(rectaStem1, rectaStem2);
System.out.println(power);
}
}
Structural Design Patterns 19

using System;

// Adapter Pattern - Simple Judith Bishop Aug 2006


// Simplest adapter using interfaces and inheritance

// Existing way requests are implemented


class Adaptee {
// Provide full precision
public double SpecificRequest (double a, double b) {
return a/b;
}
}

// Required standard for requests


interface ITarget {
// Rough estimate required
string Request (int i);
}

// Implementing the required standard via the Adaptee


class Adapter : Adaptee, ITarget {
public string Request (int i) {
return "Rough estimate is " + (int) Math.Round(SpecificRequest (i,3));
}
}

class Client {

static void Main () {


// Showing the Adapteee in stand-alone mode
Adaptee first = new Adaptee();
Console.Write("Before the new standard\nPrecise reading: ");
Console.WriteLine(first.SpecificRequest(5,3));

// What the client really wants


ITarget second = new Adapter();
Console.WriteLine("\nMoving to the new standard");
Console.WriteLine(second.Request(5));
}
}
Structural Design Patterns 20

Facade Design Pattern


GoF definition for facade design pattern is, “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.”

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.

Real World Examples for Facade Pattern


I wish to give you couple of real world examples. Lets take a car, starting a car involves
multiple steps. Imagine how it would be if you had to adjust n number of valves and
controllers. The facade you have got is just a key hole. On turn of a key it send instruction to
multiple subsystems and executes a sequence of operation and completes the objective. All
you know is a key turn which acts as a facade and simplifies your job.

Similarly consider microwave oven, it consists of components like trasnformer, capacitor,


magnetron, waveguide and some more. To perform an operation these different components
needs to be activated in a sequence. Every components has different outputs and inputs.
Imagine you will have separate external controller for all these components using which you
will heat the food. It will be complicated and cumbersome.

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

UML Diagram for Facade Design Pattern

Common Mistakes while Implementing Facade Design


Pattern
In my experience the common mistakes I have seen is,

• 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

Summary of Facade Design Pattern


• Facade provides a single interface.
• Programmers comfort is a main purpose of facade.
• Simplicity is the aim of facade pattern.
• Facade design pattern is used for promoting subsystem independence
and portability.
• Subsystem may be dependent with one another. In such case, facade can
act as a coordinator and decouple the dependencies between the
subsystems.
• Translating data to suit the interface of a subsystem is done by the
facade.

Facade Design Pattern in Java API


ExternalContext behaves as a facade for performing cookie, session scope and similar
operations. Underlying classes it uses are HttpSession, ServletContext,
javax.servlet.http.HttpServletRequest and javax.servlet.http.HttpServletResponse.

/* 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();
}

public void start() {


processor.freeze();
ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE));
processor.jump(BOOT_ADDRESS);
processor.execute();
}}
Structural Design Patterns 23

/* 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 facade = new Facade();

facade.MethodA();

facade.MethodB();

// Wait for user


Console.Read(); } }

// "Subsystem ClassA"
class SubSystemOne
{
public void MethodOne()

{Console.WriteLine( " SubSystemOne Method" ); } }

// Subsystem ClassB"
class SubSystemTwo
{
public void MethodTwo()

{Console.WriteLine( " SubSystemTwo Method" );}}

// Subsystem ClassC"
class SubSystemThree
{
public void MethodThree()

{ Console.WriteLine( " SubSystemThree Method" );}}

// Subsystem ClassD"
class SubSystemFour
{
public void MethodFour()
Structural Design Patterns 24

{Console.WriteLine( " SubSystemFour Method" );}}

// "Facade"
class Facade
{
SubSystemOne one;

SubSystemTwo two;

SubSystemThree three;

SubSystemFour four;

public Facade()

one = new SubSystemOne();

two = new SubSystemTwo();

three = new SubSystemThree();

four = new SubSystemFour();

public void MethodA()

Console.WriteLine( "\nMethodA() ---- " );

one.MethodOne();

two.MethodTwo();

four.MethodFour();

public void MethodB()

Console.WriteLine( "\nMethodB() ---- " );

two.MethodTwo();
Structural Design Patterns 25

three.MethodThree();

MethodA() ----

SubSystemOne Method

SubSystemTwo Method

SubSystemFour Method

MethodB() ----

SubSystemTwo Method

SubSystemThree Method
Structural Design Patterns 26

Composite Design Pattern


When we want to represent part-whole hierarchy, use tree structure and compose objects. A system
consists of subsystems or components. Components can further be divided into smaller components.
Further smaller components can be divided into smaller elements. This is a part-whole hierarchy.

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.

Tree for Composite


When we get a recursive structure the obvious choice for implementation is a tree. In composite
design pattern, the part-whole hierarchy can be represented as a tree. Leaves (end nodes) of a tree
being the primitive elements and the tree being the composite structure.

Uml Design for Composite Pattern


Component: (structure)

1. Component is at the top of hierarchy. It is an abstraction for the composite.


2. It declares the interface for objects in composition.
3. (optional) defines an interface for accessing a component’s parent in the recursive structure,
and implements it if that’s appropriate.

Leaf: (primitive blocks)

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)

1. Consists of child components and defines behaviour for them


2. Implements the child related operations.

public class Block implements Group {

public void assemble() {


System.out.println("Block");
}
}

public interface Group {


public void assemble();
}

import java.util.ArrayList;
import java.util.List;

public class Structure implements Group {


// Collection of child groups.
private List<Group> groups = new ArrayList<Group>();

public void assemble() {


for (Group group : groups) {
group.assemble();
}
}

// Adds the group to the structure.


public void add(Group group) {
groups.add(group);
}

// Removes the group from the structure.


public void remove(Group group) {
groups.remove(group);
}}
Structural Design Patterns 28

public class ImplementComposite {


public static void main(String[] args) {
//Initialize three blocks
Block block1 = new Block();
Block block2 = new Block();
Block block3 = new Block();

//Initialize three structure


Structure structure = new Structure();
Structure structure1 = new Structure();
Structure structure2 = new Structure();

//Composes the groups


structure1.add(block1);
structure1.add(block2);

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;

public T Name {get; set;}

public Composite (T name) {


Name = name;
list = new List <IComponent <T>> ();
}

public void Add(IComponent <T> c) {


list.Add(c);
}

// Finds the item from a particular point in the structure


// and returns the composite from which it was removed
// If not found, return the point as given
public IComponent <T> Remove(T s) {
holder = this;
IComponent <T> p = holder.Find(s);
if (holder!=null) {
Structural Design Patterns 29

(holder as Composite<T>).list.Remove(p);
return holder;
}
else
return this;
}

IComponent <T> holder=null;

// Recursively looks for an item


// Returns its reference or else null
public IComponent <T> Find (T s) {
holder = this;
if (Name.Equals(s)) return this;
IComponent <T> found=null;
foreach (IComponent <T> c in list) {
found = c.Find(s);
if (found!=null)
break;
}
return found;
}

// Displays items in a format indicating their level in the composite structure


public string Display(int depth) {
StringBuilder s = new StringBuilder(new String('-', depth));
s.Append("Set "+ Name + " length :" + list.Count + "\n");
foreach (IComponent <T> component in list) {
s.Append(component.Display(depth + 2));
}
return s.ToString();
}
}

// The Component
public class Component <T> : IComponent <T> {
public T Name {get; set;}

public Component (T name) {


Name = name;
}

public void Add(IComponent <T> c) {


Console.WriteLine("Cannot add to an item");
}

public IComponent <T> Remove(T s) {


Console.WriteLine("Cannot remove directly");
return this;
}

public string Display(int depth) {


return new String('-', depth) + Name+"\n";
}

public IComponent <T> Find (T s) {


if (s.Equals(Name))
return this;
else
return null;
}
}}
Structural Design Patterns 30

Composite Design Pattern


When we want to represent part-whole hierarchy, use tree structure and compose objects. We know
tree structure what a tree structure is and some of us don’t know what a part-whole hierarchy is. A
system consists of subsystems or components. Components can further be divided into smaller
components. Further smaller components can be divided into smaller elements. This is a part-whole
hierarchy.

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.

Real World Example


Let us consider the game of building blocks to practice composite pattern. Assume that our kit has
only three unique pieces ( 1, 2 and 4 blocks) and let us call these as primitive blocks as they will be
the end nodes in the tree structure. Objective is to build a house and it will be a step by step process.
First using primitive blocks, we should construct multiple windows, doors, walls, floor and let us call
these structures. Then use all these structure to create a house. Primitive blocks combined together
gives a structure. Multiple structures assembled together gives a house.

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

Composite Pattern Implementation


public class Block implements Group {

public void assemble() {


System.out.println("Block");
}
}

public interface Group {


public void assemble();
}

import java.util.ArrayList;
import java.util.List;

public class Structure implements Group {


// Collection of child groups.
private List<Group> groups = new ArrayList<Group>();

public void assemble() {


for (Group group : groups) {
group.assemble();
}
}

// Adds the group to the structure.


public void add(Group group) {
groups.add(group);
}

// Removes the group from the structure.


public void remove(Group group) {
groups.remove(group);
}
}

public class ImplementComposite {


public static void main(String[] args) {
//Initialize three blocks
Block block1 = new Block();
Block block2 = new Block();
Block block3 = new Block();

//Initialize three structure


Structure structure = new Structure();
Structure structure1 = new Structure();
Structure structure2 = new Structure();

//Composes the groups


structure1.add(block1);
structure1.add(block2);

structure2.add(block3);

structure.add(structure1);
structure.add(structure2);

structure.assemble();
}}
Structural Design Patterns 33

UML class diagram

participants

The classes and/or objects participating in this pattern are:

• 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

// Composite pattern -- Structural example

using System;

using System.Collections.Generic;

namespace DoFactory.GangOfFour.Composite.Structural

/// MainApp startup class for Structural

/// Composite Design Pattern.

class MainApp

/// Entry point into console application.

static void Main()

// Create a tree structure

Composite root = new Composite("root");

root.Add(new Leaf("Leaf A"));

root.Add(new Leaf("Leaf B"));

Composite comp = new Composite("Composite X");

comp.Add(new Leaf("Leaf XA"));

comp.Add(new Leaf("Leaf XB"));

root.Add(comp);

root.Add(new Leaf("Leaf C"));

// Add and remove a leaf

Leaf leaf = new Leaf("Leaf D");

root.Add(leaf);

root.Remove(leaf);

// Recursively display tree

root.Display(1);

// Wait for user

Console.ReadKey();

}
Structural Design Patterns 35

/// <summary>

/// The 'Component' abstract class

/// </summary>

abstract class Component

protected string name;

// Constructor

public Component(string name)

this.name = name;

public abstract void Add(Component c);

public abstract void Remove(Component c);

public abstract void Display(int depth);

/// <summary>

/// The 'Composite' class

/// </summary>

class Composite : Component

private List<Component> _children = new List<Component>();

// Constructor

public Composite(string name)

: base(name)

{ }

public override void Add(Component component)

{ _children.Add(component); }

public override void Remove(Component component)

{ _children.Remove(component);}
Structural Design Patterns 36

public override void Display(int depth)

{Console.WriteLine(new String('-', depth) + name);

// Recursively display child nodes

foreach (Component component in _children)

component.Display(depth + 2);

/// <summary>

/// The 'Leaf' class

/// </summary>

class Leaf : Component

// Constructor

public Leaf(string name)

: base(name)

{}

public override void Add(Component c)

{Console.WriteLine("Cannot add to a leaf");}

public override void Remove(Component c)

{Console.WriteLine("Cannot remove from a leaf");}

public override void Display(int depth)

{Console.WriteLine(new String('-', depth) + name);}

Output

-root
---Leaf A
---Leaf B
---Composite X
-----Leaf XA
-----Leaf XB
---Leaf C

You might also like