Structural Design Patterns
In plain words
Structural patterns are mostly concerned with object composition or in other words how the entities can use each other. Or yet another explanation would be, they help in answering "How to build a software component"
Wikipedia says
In software engineering, structural design patterns are design patterns that ease the design by identifying a simple way to realize relationships between entities.
Adapter
Real world example
Consider that you have some pictures in your memory card and you need to transfer them to your computer. In order to transfer them you need some kind of adapter that is compatible with your computer ports so that you can attach memory card to your computer. In this case card reader is an adapter.Another example would be the famous power adapter; a three legged plug can't be connected to a two pronged outlet, it needs to use a power adapter that makes it compatible with the two pronged outlet.Yet another example would be a translator translating words spoken by one person to another
In plain words
Adapter pattern lets you wrap an otherwise incompatible object in an adapter to make it compatible with another class.
Wikipedia says
In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code.
Programmatic Example
Consider a game where there is a hunter and he hunts lions.
First we have an interface Lion
that all types of lions have to implement
- interface Lion
- {
- public function roar();
- }
- class AfricanLion implements Lion
- {
- public function roar()
- {
- }
- }
- class AsianLion implements Lion
- {
- public function roar()
- {
- }
- }
And hunter expects any implementation of Lion
interface to hunt.
- class Hunter
- {
- public function hunt(Lion $lion)
- {
- $lion->roar();
- }
- }
Now let's say we have to add a WildDog
in our game so that hunter can hunt that also. But we can't do that directly because dog has a different interface. To make it compatible for our hunter, we will have to create an adapter that is compatible
- // This needs to be added to the game
- class WildDog
- {
- public function bark()
- {
- }
- }
- // Adapter around wild dog to make it compatible with our game
- class WildDogAdapter implements Lion
- {
- protected $dog;
- public function __construct(WildDog $dog)
- {
- $this->dog = $dog;
- }
- public function roar()
- {
- $this->dog->bark();
- }
- }
And now the WildDog
can be used in our game using WildDogAdapter
.
- $wildDog = new WildDog();
- $wildDogAdapter = new WildDogAdapter($wildDog);
- $hunter = new Hunter();
- $hunter->hunt($wildDogAdapter);
Bridge
Real world example
Consider you have a website with different pages and you are supposed to allow the user to change the theme. What would you do Create multiple copies of each of the pages for each of the themes or would you just create separate theme and load them based on the user's preferences Bridge pattern allows you to do the second i.e.
In Plain Words
Bridge pattern is about preferring composition over inheritance. Implementation details are pushed from a hierarchy to another object with a separate hierarchy.
Wikipedia says
The bridge pattern is a design pattern used in software engineering that is meant to "decouple an abstraction from its implementation so that the two can vary independently"
Programmatic Example
Translating our WebPage example from above. Here we have the WebPage
hierarchy
- interface WebPage
- {
- public function __construct(Theme $theme);
- public function getContent();
- }
- class About implements WebPage
- {
- protected $theme;
- public function __construct(Theme $theme)
- {
- $this->theme = $theme;
- }
- public function getContent()
- {
- return "About page in " . $this->theme->getColor();
- }
- }
- class Careers implements WebPage
- {
- protected $theme;
- public function __construct(Theme $theme)
- {
- $this->theme = $theme;
- }
- public function getContent()
- {
- return "Careers page in " . $this->theme->getColor();
- }
- }
And the separate theme hierarchy
- interface Theme
- {
- public function getColor();
- }
- class DarkTheme implements Theme
- {
- public function getColor()
- {
- return 'Dark Black';
- }
- }
- class LightTheme implements Theme
- {
- public function getColor()
- {
- return 'Off white';
- }
- }
- class AquaTheme implements Theme
- {
- public function getColor()
- {
- return 'Light blue';
- }
- }
And both the hierarchies
- $darkTheme = new DarkTheme();
- $about = new About($darkTheme);
- $careers = new Careers($darkTheme);
- echo $about->getContent(); // "About page in Dark Black";
- echo $careers->getContent(); // "Careers page in Dark Black";
Composite
Real world example
Every organization is composed of employees. Each of the employees has the same features i.e. has a salary, has some responsibilities, may or may not report to someone, may or may not have some subordinates etc.
In plain words
Composite pattern lets clients treat the individual objects in a uniform manner.
Wikipedia says
In software engineering, the composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects is to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly.
Programmatic Example
Taking our employees example from above. Here we have different employee types
- interface Employee
- {
- public function __construct(string $name, float $salary);
- public function getName(): string;
- public function setSalary(float $salary);
- public function getSalary(): float;
- public function getRoles(): array;
- }
- class Developer implements Employee
- {
- protected $salary;
- protected $name;
- protected $roles;
- public function __construct(string $name, float $salary)
- {
- $this->name = $name;
- $this->salary = $salary;
- }
- public function getName(): string
- {
- return $this->name;
- }
- public function setSalary(float $salary)
- {
- $this->salary = $salary;
- }
- public function getSalary(): float
- {
- return $this->salary;
- }
- public function getRoles(): array
- {
- return $this->roles;
- }
- }
- class Designer implements Employee
- {
- protected $salary;
- protected $name;
- protected $roles;
- public function __construct(string $name, float $salary)
- {
- $this->name = $name;
- $this->salary = $salary;
- }
- public function getName(): string
- {
- return $this->name;
- }
- public function setSalary(float $salary)
- {
- $this->salary = $salary;
- }
- public function getSalary(): float
- {
- return $this->salary;
- }
- public function getRoles(): array
- {
- return $this->roles;
- }
- }
Then we have an organization which consists of several different types of employees
- class Organization
- {
- protected $employees;
- public function addEmployee(Employee $employee)
- {
- $this->employees[] = $employee;
- }
- public function getNetSalaries(): float
- {
- $netSalary = 0;
- foreach ($this->employees as $employee) {
- $netSalary += $employee->getSalary();
- }
- return $netSalary;
- }
- }
And then it can be used as
- // Prepare the employees
- $john = new Developer('John Doe', 12000);
- $jane = new Designer('Jane Doe', 15000);
- // Add them to organization
- $organization = new Organization();
- $organization->addEmployee($john);
- $organization->addEmployee($jane);
- echo "Net salaries: " . $organization->getNetSalaries(); // Net Salaries: 27000
☕ Decorator
Real world example
Imagine you run a car service shop offering multiple services. Now how do you calculate the bill to be charged You pick one service and dynamically keep adding to it the prices for the provided services till you get the final cost. Here each type of service is a decorator.
In plain words
Decorator pattern lets you dynamically change the behavior of an object at run time by wrapping them in an object of a decorator class.
Wikipedia says
In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern.
Programmatic Example
Lets take coffee for example. First of all we have a simple coffee implementing the coffee interface
- interface Coffee
- {
- public function getCost();
- public function getDescription();
- }
- class SimpleCoffee implements Coffee
- {
- public function getCost()
- {
- return 10;
- }
- public function getDescription()
- {
- return 'Simple coffee';
- }
- }
We want to make the code extensible to allow options to modify it if required. Lets make some add-ons (decorators)
- class MilkCoffee implements Coffee
- {
- protected $coffee;
- public function __construct(Coffee $coffee)
- {
- $this->coffee = $coffee;
- }
- public function getCost()
- {
- return $this->coffee->getCost() + 2;
- }
- public function getDescription()
- {
- return $this->coffee->getDescription() . ', milk';
- }
- }
- class WhipCoffee implements Coffee
- {
- protected $coffee;
- public function __construct(Coffee $coffee)
- {
- $this->coffee = $coffee;
- }
- public function getCost()
- {
- return $this->coffee->getCost() + 5;
- }
- public function getDescription()
- {
- return $this->coffee->getDescription() . ', whip';
- }
- }
- class VanillaCoffee implements Coffee
- {
- protected $coffee;
- public function __construct(Coffee $coffee)
- {
- $this->coffee = $coffee;
- }
- public function getCost()
- {
- return $this->coffee->getCost() + 3;
- }
- public function getDescription()
- {
- return $this->coffee->getDescription() . ', vanilla';
- }
- }
Lets make a coffee now
- $someCoffee = new SimpleCoffee();
- echo $someCoffee->getCost(); // 10
- echo $someCoffee->getDescription(); // Simple Coffee
- $someCoffee = new MilkCoffee($someCoffee);
- echo $someCoffee->getCost(); // 12
- echo $someCoffee->getDescription(); // Simple Coffee, milk
- $someCoffee = new WhipCoffee($someCoffee);
- echo $someCoffee->getCost(); // 17
- echo $someCoffee->getDescription(); // Simple Coffee, milk, whip
- $someCoffee = new VanillaCoffee($someCoffee);
- echo $someCoffee->getCost(); // 20
- echo $someCoffee->getDescription(); // Simple Coffee, milk, whip, vanilla
Facade
Real world example
How do you turn on the computer "Hit the power button" you say! That is what you believe because you are using a simple interface that computer provides on the outside, internally it has to do a lot of stuff to make it happen. This simple interface to the complex subsystem is a facade.
In plain words
Facade pattern provides a simplified interface to a complex subsystem.
Wikipedia says
A facade is an object that provides a simplified interface to a larger body of code, such as a class library.
Programmatic Example
Taking our computer example from above. Here we have the computer class
- class Computer
- {
- public function getElectricShock()
- {
- echo "Ouch!";
- }
- public function makeSound()
- {
- echo "Beep beep!";
- }
- public function showLoadingScreen()
- {
- echo "Loading..";
- }
- public function bam()
- {
- echo "Ready to be used!";
- }
- public function closeEverything()
- {
- echo "Bup bup bup buzzzz!";
- }
- public function sooth()
- {
- echo "Zzzzz";
- }
- public function pullCurrent()
- {
- echo "Haaah!";
- }
- }
Here we have the facade
- class ComputerFacade
- {
- protected $computer;
- public function __construct(Computer $computer)
- {
- $this->computer = $computer;
- }
- public function turnOn()
- {
- $this->computer->getElectricShock();
- $this->computer->makeSound();
- $this->computer->showLoadingScreen();
- $this->computer->bam();
- }
- public function turnOff()
- {
- $this->computer->closeEverything();
- $this->computer->pullCurrent();
- $this->computer->sooth();
- }
- }
Now to use the facade
- $computer = new ComputerFacade(new Computer());
- $computer->turnOn(); // Ouch! Beep beep! Loading.. Ready to be used!
- $computer->turnOff(); // Bup bup buzzz! Haah! Zzzzz
Flyweight
Real world example
Did you ever have fresh tea from some stall They often make more than one cup that you demanded and save the rest for any other customer so to save the resources e.g. gas etc. Flyweight pattern is all about that i.e. sharing.
In plain words
It is used to minimize memory usage or computational expenses by sharing as much as possible with similar objects.
Wikipedia says
In computer programming, flyweight is a software design pattern. A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory.
Programmatic example
Translating our tea example from above. First of all we have tea types and tea maker
- // Anything that will be cached is flyweight.
- // Types of tea here will be flyweights.
- class KarakTea
- {
- }
- // Acts as a factory and saves the tea
- class TeaMaker
- {
- protected $availableTea = [];
- public function make($preference)
- {
- if (empty($this->availableTea[$preference])) {
- $this->availableTea[$preference] = new KarakTea();
- }
- return $this->availableTea[$preference];
- }
- }
Then we have the TeaShop
which takes orders and serves them
- class TeaShop
- {
- protected $orders;
- protected $teaMaker;
- public function __construct(TeaMaker $teaMaker)
- {
- $this->teaMaker = $teaMaker;
- }
- public function takeOrder(string $teaType, int $table)
- {
- $this->orders[$table] = $this->teaMaker->make($teaType);
- }
- public function serve()
- {
- foreach ($this->orders as $table => $tea) {
- echo "Serving tea to table# " . $table;
- }
- }
- }
And it can be used as below
- $teaMaker = new TeaMaker();
- $shop = new TeaShop($teaMaker);
- $shop->takeOrder('less sugar', 1);
- $shop->takeOrder('more milk', 2);
- $shop->takeOrder('without sugar', 5);
- $shop->serve();
- // Serving tea to table# 1
- // Serving tea to table# 2
- // Serving tea to table# 5
Proxy
Real world example
Have you ever used an access card to go through a door There are multiple options to open that door i.e. it can be opened either using access card or by pressing a button that bypasses the security. The door's main functionality is to open but there is a proxy added on top of it to add some functionality. Let me better explain it using the code example below.
In plain words
Using the proxy pattern, a class represents the functionality of another class.
Wikipedia says
A proxy, in its most general form, is a class functioning as an interface to something else. A proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes. Use of the proxy can simply be forwarding to the real object, or can provide additional logic. In the proxy extra functionality can be provided, for example caching when operations on the real object are resource intensive, or checking preconditions before operations on the real object are invoked.
Programmatic Example
Taking our security door example from above. Firstly we have the door interface and an implementation of door
- interface Door
- {
- public function open();
- public function close();
- }
- class LabDoor implements Door
- {
- public function open()
- {
- echo "Opening lab door";
- }
- public function close()
- {
- echo "Closing the lab door";
- }
- }
Then we have a proxy to secure any doors that we want
- class SecuredDoor
- {
- protected $door;
- public function __construct(Door $door)
- {
- $this->door = $door;
- }
- public function open($password)
- {
- if ($this->authenticate($password)) {
- $this->door->open();
- } else {
- echo "Big no! It ain't possible.";
- }
- }
- public function authenticate($password)
- {
- return $password === '$ecr@t';
- }
- public function close()
- {
- $this->door->close();
- }
- }
And here is how it can be used
- $door = new SecuredDoor(new LabDoor());
- $door->open('invalid'); // Big no! It ain't possible.
- $door->open('$ecr@t'); // Opening lab door
- $door->close(); // Closing lab door
Yet another example would be some sort of data-mapper implementation. For example, I recently made an ODM (Object Data Mapper) for MongoDB using this pattern where I wrote a proxy around mongo classes while utilizing the magic method __call()
. All the method calls were proxied to the original mongo class and result retrieved was returned as it is but in case of find
or findOne
data was mapped to the required class objects and the object was returned instead of Cursor
.