├── .gitignore
├── Adapter pattern
├── Adapters
│ └── TurkeyAdapter.php
├── Entities
│ ├── MallardDuck.php
│ └── WildTurkey.php
├── Interfaces
│ ├── Duck.php
│ └── Turkey.php
├── Main.php
└── README.md
├── Command pattern
├── Commands
│ ├── CeilingFan
│ │ ├── CeilingFanHighCommand.php
│ │ ├── CeilingFanLowCommand.php
│ │ ├── CeilingFanMediumCommand.php
│ │ └── CeilingFanOffCommand.php
│ ├── GarageDoor
│ │ ├── GarageDoorClose.php
│ │ └── GarageDoorOpen.php
│ ├── Hottub
│ │ ├── HottubOff.php
│ │ └── HottubOn.php
│ ├── Light
│ │ ├── LightOffCommand.php
│ │ └── LightOnCommand.php
│ └── Stereo
│ │ ├── StereoOffCommand.php
│ │ └── StereoOnCommand.php
├── Entities
│ ├── CeilingFan.php
│ ├── GarageDoor.php
│ ├── Hottub.php
│ ├── Light.php
│ └── Stereo.php
├── Interfaces
│ ├── Command.php
│ └── NoCommand.php
├── Invocations
│ └── RemoteControl.php
├── Main.php
├── README.md
└── UML.jpg
├── Composite pattern
├── Components
│ └── MenuComponent.php
├── Entities
│ ├── Menu.php
│ ├── MenuItem.php
│ └── Waitress.php
├── Interators
│ ├── CompositeIterator.php
│ ├── MenuComponentsIterator.php
│ └── NullIterator.php
├── Interfaces
│ └── IteratorInterface.php
├── Main.php
├── README.md
├── UML.jpg
└── UnsupportedOperationException.php
├── Decorator pattern
├── Beverages
│ ├── DarkRoast.php
│ ├── Decaf.php
│ ├── Espresso.php
│ └── HouseBlend.php
├── Condiments
│ ├── Mocha.php
│ ├── Soy.php
│ ├── SteamedMilk.php
│ └── Whip.php
├── Entities
│ ├── Beverage.php
│ └── CondimentDecorator.php
├── Main.php
└── README.md
├── Facade pattern
├── Components
│ ├── Amplifier.php
│ ├── CdPlayer.php
│ ├── DvdPlayer.php
│ ├── PopcornPopper.php
│ ├── Projector.php
│ ├── Screen.php
│ ├── TheaterLights.php
│ └── Tuner.php
├── Facades
│ └── HomeTheaterFacade.php
├── Main.php
└── README.md
├── Factory pattern
├── Entities
│ ├── CheesePizza.php
│ ├── ClamPizza.php
│ ├── PepperoniPizza.php
│ └── VeggiePizza.php
├── Factories
│ └── SimpleFactory.php
├── Interfaces
│ ├── Pizza.php
│ └── PizzaStore.php
├── Main.php
└── README.md
├── Iterator pattern
├── Entities
│ ├── DinerMenu.php
│ ├── MenuItem.php
│ ├── PancakeHouseMenu.php
│ └── Waitress.php
├── Interfaces
│ ├── Iterator.php
│ └── Menu.php
├── Iterators
│ ├── DinerMenuIterator.php
│ └── PancakeHouseMenuIterator.php
├── Main.php
└── README.md
├── Observer pattern
├── Entities
│ ├── CurrentConditionsDisplay.php
│ ├── ForecastDisplay.php
│ └── StatisticsDisplay.php
├── Interfaces
│ ├── DisplayElement.php
│ ├── Observer.php
│ └── Subject.php
├── Main.php
├── Objects
│ └── WeatherData.php
└── README.md
├── Proxy pattern
├── Entities
│ └── RealFile.php
├── Interfaces
│ └── File.php
├── Main.php
├── Proxies
│ └── ProxyFile.php
├── README.md
└── test.txt
├── README.md
├── Singleton pattern
├── ChocolateBoiler.php
└── README.md
├── State pattern
├── Entities
│ └── GumballMachine.php
├── Interfaces
│ └── State.php
├── Main.php
├── README.md
└── States
│ ├── HasQuarterState.php
│ ├── NoQuarterState.php
│ ├── SoldState.php
│ ├── SoldoutState.php
│ └── WinnerState.php
├── Strategy pattern
├── Behaviors
│ ├── FlyBehavior.php
│ ├── FlyBehaviors
│ │ ├── FlyNoWay.php
│ │ ├── FlyRocketPowered.php
│ │ └── FlyWithWings.php
│ ├── QuackBehavior.php
│ └── QuackBehaviors
│ │ ├── MuteQuack.php
│ │ ├── Quack.php
│ │ └── Squack.php
├── Main.php
├── Objects
│ ├── MallardDuck.php
│ └── RubberDuck.php
├── README.md
└── Types
│ └── Duck.php
├── Template Method pattern
├── Entities
│ ├── Coffee.php
│ └── Tea.php
├── Main.php
├── README.md
└── Templates
│ └── CaffeineBeverage.php
└── composer.json
/.gitignore:
--------------------------------------------------------------------------------
1 | composer.phar
2 | /vendor/
3 | .idea
4 |
5 | # Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
6 | # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
7 | # composer.lock
8 |
--------------------------------------------------------------------------------
/Adapter pattern/Adapters/TurkeyAdapter.php:
--------------------------------------------------------------------------------
1 | turkey = $turkey;
16 | }
17 |
18 | public function quack()
19 | {
20 | $this->turkey->gobble();
21 | }
22 |
23 | public function fly()
24 | {
25 | for($i=0; $i < 5 ; $i++)
26 | {
27 | $this->turkey->fly();
28 | }
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/Adapter pattern/Entities/MallardDuck.php:
--------------------------------------------------------------------------------
1 | gobble();
15 | $turkey->fly();
16 |
17 | print "The Duck says...\n";
18 | $duck->quack();
19 | $duck->fly();
20 |
21 | print "The TurkeyAdapter says...\n";
22 | $turkeyAdapter->quack();
23 | $turkeyAdapter->fly();
--------------------------------------------------------------------------------
/Adapter pattern/README.md:
--------------------------------------------------------------------------------
1 | # Adapter Pattern
2 | Convert the interface of a class into another interface clients expect.let's classes work together that couldn't otherwise because of incompatible interfaces.
3 | ##### two adapter types
4 | - Class adapter : depends on multiple inheritance that the adapter will inherit the target class and adaptee class.
5 | - Object adapter : depends on composition that the adapter will be composed of the adaptee objects provides more flexibility.
6 |
7 | ### Problem
8 | We have ducks and turkeys every one can fly but not every one make the same sound ducks duck and turkey's gobble so we need an adapter to can gobble and fly the same way as ducks do
9 |
10 | ### In the future (we want)
11 | - add more composition between the turkeys and other kind of birds.
12 |
13 | ### Now pattern talks
14 |
15 | #### UML Diagram
16 | 
17 | #### Folder Structure
18 | read the following folder structure and then have a look on the code
19 | ```
20 | ├───Adapters (holds the application addapter)
21 | │ TurkeyAdapter.php
22 | │
23 | ├───Entities (animals ( classes ) we will use on the adapter)
24 | │ MallardDuck.php
25 | │ WildTurkey.php
26 | │
27 | └───Interfaces (interfaces for our application)
28 | Duck.php
29 | Turkey.php
30 |
31 | ```
32 |
33 | -- Run `Main.php` and trace the execution to get familiar with the pattern.
--------------------------------------------------------------------------------
/Command pattern/Commands/CeilingFan/CeilingFanHighCommand.php:
--------------------------------------------------------------------------------
1 | ceilingFan = $ceilingFan;
17 | }
18 |
19 | public function execute()
20 | {
21 | $this->prevSpeed = $this->ceilingFan->getSpeed();
22 | $this->ceilingFan->high();
23 | }
24 |
25 | public function undo()
26 | {
27 | switch ($this->prevSpeed){
28 | case CeilingFan::$HIGH:
29 | $this->ceilingFan->high();
30 | break;
31 | case CeilingFan::$MEDIUM:
32 | $this->ceilingFan->medium();
33 | break;
34 | case CeilingFan::$LOW:
35 | $this->ceilingFan->low();
36 | break;
37 | case CeilingFan::$OFF:
38 | $this->ceilingFan->off();
39 | break;
40 | }
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/Command pattern/Commands/CeilingFan/CeilingFanLowCommand.php:
--------------------------------------------------------------------------------
1 | ceilingFan = $ceilingFan;
17 | }
18 |
19 | public function execute()
20 | {
21 | $this->prevSpeed = $this->ceilingFan->getSpeed();
22 | $this->ceilingFan->low();
23 | }
24 |
25 | public function undo()
26 | {
27 | switch ($this->prevSpeed){
28 | case CeilingFan::$HIGH:
29 | $this->ceilingFan->high();
30 | break;
31 | case CeilingFan::$MEDIUM:
32 | $this->ceilingFan->medium();
33 | break;
34 | case CeilingFan::$LOW:
35 | $this->ceilingFan->low();
36 | break;
37 | case CeilingFan::$OFF:
38 | $this->ceilingFan->off();
39 | break;
40 | }
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/Command pattern/Commands/CeilingFan/CeilingFanMediumCommand.php:
--------------------------------------------------------------------------------
1 | ceilingFan = $ceilingFan;
17 | }
18 |
19 | public function execute()
20 | {
21 | $this->prevSpeed = $this->ceilingFan->getSpeed();
22 | $this->ceilingFan->medium();
23 | }
24 |
25 | public function undo()
26 | {
27 | switch ($this->prevSpeed){
28 | case CeilingFan::$HIGH:
29 | $this->ceilingFan->high();
30 | break;
31 | case CeilingFan::$MEDIUM:
32 | $this->ceilingFan->medium();
33 | break;
34 | case CeilingFan::$LOW:
35 | $this->ceilingFan->low();
36 | break;
37 | case CeilingFan::$OFF:
38 | $this->ceilingFan->off();
39 | break;
40 | }
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/Command pattern/Commands/CeilingFan/CeilingFanOffCommand.php:
--------------------------------------------------------------------------------
1 | ceilingFan = $ceilingFan;
17 | }
18 |
19 | public function execute()
20 | {
21 | $this->prevSpeed = $this->ceilingFan->getSpeed();
22 | $this->ceilingFan->off();
23 | }
24 |
25 | public function undo()
26 | {
27 | switch ($this->prevSpeed){
28 | case CeilingFan::$HIGH:
29 | $this->ceilingFan->high();
30 | break;
31 | case CeilingFan::$MEDIUM:
32 | $this->ceilingFan->medium();
33 | break;
34 | case CeilingFan::$LOW:
35 | $this->ceilingFan->low();
36 | break;
37 | case CeilingFan::$OFF:
38 | $this->ceilingFan->off();
39 | break;
40 | }
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/Command pattern/Commands/GarageDoor/GarageDoorClose.php:
--------------------------------------------------------------------------------
1 | door = $door;
16 | }
17 |
18 | public function execute()
19 | {
20 | $this->door->close();
21 | }
22 |
23 | public function undo()
24 | {
25 | $this->door->open();
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/Command pattern/Commands/GarageDoor/GarageDoorOpen.php:
--------------------------------------------------------------------------------
1 | door = $door;
16 | }
17 |
18 | public function execute()
19 | {
20 | $this->door->open();
21 | }
22 |
23 | public function undo()
24 | {
25 | $this->door->close();
26 | }
27 | }
--------------------------------------------------------------------------------
/Command pattern/Commands/Hottub/HottubOff.php:
--------------------------------------------------------------------------------
1 | hottub = $hottub;
17 | }
18 |
19 | public function execute()
20 | {
21 | $this->hottub->off();
22 | }
23 |
24 | public function undo()
25 | {
26 | $this->hottub->off();
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/Command pattern/Commands/Hottub/HottubOn.php:
--------------------------------------------------------------------------------
1 | hottub = $hottub;
16 | }
17 |
18 | public function execute()
19 | {
20 | $this->hottub->on();
21 | }
22 |
23 | public function undo()
24 | {
25 | $this->hottub->off();
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/Command pattern/Commands/Light/LightOffCommand.php:
--------------------------------------------------------------------------------
1 | light = $light;
16 | }
17 |
18 | public function execute()
19 | {
20 | $this->light->off();
21 | }
22 |
23 | public function undo()
24 | {
25 | $this->light->on();
26 | }
27 | }
--------------------------------------------------------------------------------
/Command pattern/Commands/Light/LightOnCommand.php:
--------------------------------------------------------------------------------
1 | light = $light;
15 | }
16 |
17 | public function execute()
18 | {
19 | $this->light->on();
20 | }
21 |
22 | public function undo()
23 | {
24 | $this->light->off();
25 | }
26 |
27 | public function test()
28 | {
29 | echo "testing";
30 | }
31 | }
--------------------------------------------------------------------------------
/Command pattern/Commands/Stereo/StereoOffCommand.php:
--------------------------------------------------------------------------------
1 | stereo = $stereo;
16 | }
17 |
18 | public function execute()
19 | {
20 | $this->stereo->off();
21 | }
22 |
23 | public function undo()
24 | {
25 | $this->stereo->on();
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/Command pattern/Commands/Stereo/StereoOnCommand.php:
--------------------------------------------------------------------------------
1 | stereo = $stereo;
16 | }
17 |
18 | public function execute()
19 | {
20 | $this->stereo->on();
21 | }
22 |
23 | public function undo()
24 | {
25 | $this->stereo->off();
26 |
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/Command pattern/Entities/CeilingFan.php:
--------------------------------------------------------------------------------
1 | roomName = $roomName;
20 | }
21 |
22 | public function high()
23 | {
24 | $this->speed = $this->HIGH;
25 | print "Ceiling fan is high.\n";
26 | }
27 |
28 | public function medium()
29 | {
30 | $this->speed = $this->MEDIUM;
31 | print "Ceiling fan is medium.\n";
32 | }
33 |
34 | public function low()
35 | {
36 | $this->speed = $this->LOW;
37 | print "Ceiling fan is low.\n";
38 | }
39 |
40 | public function off()
41 | {
42 | $this->speed = $this->OFF;
43 | print "Ceiling fan is off.\n";
44 | }
45 |
46 | public function getSpeed()
47 | {
48 | return $this->speed;
49 | }
50 | }
--------------------------------------------------------------------------------
/Command pattern/Entities/GarageDoor.php:
--------------------------------------------------------------------------------
1 | roomName = $roomName;
13 | }
14 |
15 | public function on()
16 | {
17 | echo "Light is on.\n";
18 | }
19 |
20 | public function off()
21 | {
22 | echo "Light is off.\n";
23 | }
24 | }
--------------------------------------------------------------------------------
/Command pattern/Entities/Stereo.php:
--------------------------------------------------------------------------------
1 | roomName = $roomName;
13 | }
14 |
15 | public function on()
16 | {
17 | print "Stereo is on";
18 | }
19 |
20 | public function off()
21 | {
22 | print "Stereo is off";
23 | }
24 |
25 | public function setCD()
26 | {
27 | print "\t Set CD.\n";
28 | }
29 |
30 | public function setDvd()
31 | {
32 | print "\t Set Dvd.\n";
33 | }
34 |
35 | public function setRadio()
36 | {
37 | print "\t Set Radio.\n";
38 | }
39 |
40 | public function setVolume( $volume )
41 | {
42 | print "\t Set volume to $volume.\n";
43 | }
44 | }
--------------------------------------------------------------------------------
/Command pattern/Interfaces/Command.php:
--------------------------------------------------------------------------------
1 | onCommands[$i] = NoCommand::class;
19 | $this->offCommands[$i] = NoCommand::class;
20 | }
21 |
22 | $this->undoCommand = NoCommand::class;
23 | }
24 |
25 | public function setCommand( $slot,Command $onCommand,Command $offCommand )
26 | {
27 | $this->onCommands[$slot] = $onCommand;
28 | $this->offCommands[$slot] = $offCommand;
29 | }
30 |
31 | public function onButtonWasPushed( $slot )
32 | {
33 | $this->onCommands[$slot]->execute();
34 | $this->undoCommand = $this->onCommands[$slot];
35 | }
36 |
37 | public function offButtonWasPushed( $slot )
38 | {
39 | $this->offCommands[$slot]->execute();
40 | $this->undoCommand = $this->offCommands[$slot];
41 | }
42 |
43 | public function undoButtonWasPushed()
44 | {
45 | $this->undoCommand->undo();
46 | }
47 | }
--------------------------------------------------------------------------------
/Command pattern/Main.php:
--------------------------------------------------------------------------------
1 | setCommand(0, $livingRoomLightOn, $livingRoomLightOff);
41 | $remoteControl->setCommand(1, $kitchenLightOn, $kitchenLightOff);
42 | $remoteControl->setCommand(2, $ceilingFanHigh, $ceilingFanOff);
43 | $remoteControl->setCommand(3, $stereoOn, $stereoOff);
44 |
45 | $remoteControl->onButtonWasPushed(0);
46 | $remoteControl->offButtonWasPushed(0);
47 | $remoteControl->undoButtonWasPushed();
48 |
49 |
--------------------------------------------------------------------------------
/Command pattern/README.md:
--------------------------------------------------------------------------------
1 | # Command Pattern (Encapsulating Invocation)
2 | Encapsulates a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
3 |
4 | ### Problem
5 | We have a simple home operations and a remote control and we want to create a program to automate the task of controlling the come using the remote.
6 |
7 | ### In the future (we want)
8 | - add more button functions to the remote control.
9 | - undo specific button from the remote.
10 | - create a button that will execute more functions at the same time.
11 |
12 | ### Now pattern talks
13 |
14 | #### UML Diagram
15 | 
16 | #### Folder Structure
17 | read the following folder structure and then have a look on the code
18 | ```
19 | ├───Commands (holds the commands categorized by the device type)
20 | │ ├───CeilingFan
21 | │ │ CeilingFanHighCommand.php
22 | │ │ CeilingFanLowCommand.php
23 | │ │ CeilingFanMediumCommand.php
24 | │ │ CeilingFanOffCommand.php
25 | │ │
26 | │ ├───GarageDoor
27 | │ │ GarageDoorClose.php
28 | │ │ GarageDoorOpen.php
29 | │ │
30 | │ ├───Hottub
31 | │ │ HottubOff.php
32 | │ │ HottubOn.php
33 | │ │
34 | │ ├───Light
35 | │ │ LightOffCommand.php
36 | │ │ LightOnCommand.php
37 | │ │
38 | │ └───Stereo
39 | │ StereoOffCommand.php
40 | │ StereoOnCommand.php
41 | │
42 | ├───Entities (holds the main functions of every device)
43 | │ CeilingFan.php
44 | │ GarageDoor.php
45 | │ Hottub.php
46 | │ Light.php
47 | │ Stereo.php
48 | │
49 | ├───Interfaces (app interfaces)
50 | │ Command.php
51 | │ NoCommand.php
52 | │
53 | └───Invocations (the invocations for our commands)
54 | RemoteControl.php
55 |
56 | ```
57 |
58 | -- Run `Main.php` and trace the execution to get familiar with the pattern.
--------------------------------------------------------------------------------
/Command pattern/UML.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aa-ahmed-aa/Design_Pattern/d1640fb645d2f939a633e26db1b6b885c1cb3c5a/Command pattern/UML.jpg
--------------------------------------------------------------------------------
/Composite pattern/Components/MenuComponent.php:
--------------------------------------------------------------------------------
1 | name = $name;
21 | $this->description = $description;
22 | }
23 |
24 | public function add(MenuComponent $menuComponent)
25 | {
26 | $this->menuComponents[] = $menuComponent;
27 | }
28 |
29 | public function remove(MenuComponent $menuComponent)
30 | {
31 | if (($key = array_search( $menuComponent, $this->menuComponents ) ) !== false) {
32 | unset($this->menuComponents[$key]);
33 | }
34 | }
35 |
36 | public function getChild(int $i)
37 | {
38 | return $this->menuComponents[$i];
39 | }
40 |
41 | public function getName()
42 | {
43 | return $this->name;
44 | }
45 |
46 | public function getDescription()
47 | {
48 | return $this->description;
49 | }
50 |
51 | public function printMenu()
52 | {
53 | print "\n" . $this->getName() . " -- " . $this->getDescription() . "\n------------------------------------\n";
54 |
55 | $iterator = new MenuComponentsIterator($this->menuComponents);
56 |
57 | while( $iterator->hasNext() )
58 | {
59 | $menuComponent = $iterator->next();
60 | $menuComponent->printMenu();
61 | }
62 | }
63 |
64 | public function createIterator()
65 | {
66 | if( is_null($this->compositeIterator) )
67 | {
68 | $this->compositeIterator = new CompositeIterator( new MenuComponentsIterator($this->menuComponents) );
69 | }
70 |
71 | return $this->compositeIterator;
72 | }
73 | }
--------------------------------------------------------------------------------
/Composite pattern/Entities/MenuItem.php:
--------------------------------------------------------------------------------
1 | name = $name;
21 | $this->description = $description;
22 | $this->vegetarian = $vegetarian;
23 | $this->price = $price;
24 | }
25 |
26 | public function getName()
27 | {
28 | return $this->name;
29 | }
30 |
31 | public function getDescription()
32 | {
33 | return $this->description;
34 | }
35 |
36 | public function getPrice()
37 | {
38 | return $this->price;
39 | }
40 |
41 | public function isVegetarian()
42 | {
43 | return $this->vegetarian;
44 | }
45 |
46 | public function printMenu()
47 | {
48 | echo " ". $this->getName();
49 | if($this->isVegetarian())
50 | echo "(v)";
51 | echo ", " .$this->getPrice();
52 | echo " -- " . $this->getDescription() . "\n";
53 | }
54 |
55 | public function createIterator()
56 | {
57 | if(is_null($this->nullIterator))
58 | $this->nullIterator = new NullIterator();
59 | return $this->nullIterator;
60 | }
61 | }
--------------------------------------------------------------------------------
/Composite pattern/Entities/Waitress.php:
--------------------------------------------------------------------------------
1 | allMenus = $allMenus;
15 | }
16 |
17 | public function printMenu(){
18 | $this->allMenus->printMenu();
19 | }
20 | }
--------------------------------------------------------------------------------
/Composite pattern/Interators/CompositeIterator.php:
--------------------------------------------------------------------------------
1 | stack, $iterator);
13 | }
14 | public function next(){
15 | if($this->hasNext()){
16 | $iterator = $this->array_peek($this->stack);
17 | $component = $iterator->next();
18 | if($component instanceof Menu) {
19 | array_push($this->stack , $component->createIterator());
20 | }
21 | return $component;
22 | }
23 | return NULL;
24 | }
25 | public function hasNext() {
26 | if(count($this->stack) <= 0 ) return false;
27 | $iterator = $this->array_peek($this->stack);
28 | if(!$iterator->hasNext()){
29 | array_pop($this->stack);
30 | return $this->hasNext();
31 | }
32 | return true;
33 | }
34 | private function array_peek(array $array){
35 | return $array[count($array) - 1];
36 | }
37 | }
--------------------------------------------------------------------------------
/Composite pattern/Interators/MenuComponentsIterator.php:
--------------------------------------------------------------------------------
1 | menuItems = $array;
16 | }
17 |
18 | public function next()
19 | {
20 | return $this->menuItems[$this->index++];
21 | }
22 |
23 | public function hasNext()
24 | {
25 | if($this->index >= count($this->menuItems))
26 | return false;
27 | return true;
28 | }
29 | }
--------------------------------------------------------------------------------
/Composite pattern/Interators/NullIterator.php:
--------------------------------------------------------------------------------
1 | add( $pancakeHouseMenu );
16 | $allMenus->add( $dinerMenu );
17 | $allMenus->add( $cafeMenu );
18 |
19 | //################################################################################################
20 | //add pancake house menu items
21 | $pancakeHouseMenu->add(new MenuItem("K&B’s Pancake Breakfast",
22 | "Pancakes with scrambled eggs, and toast ",
23 | true,
24 | 2.99));
25 | $pancakeHouseMenu->add(new MenuItem("Regular Pancake Breakfast",
26 | "Pancakes with fried eggs, sausage",
27 | false,
28 | 2.99));
29 | $pancakeHouseMenu->add(new MenuItem("Blueberry Pancakes",
30 | "Pancakes made with fresh blueberries",
31 | true,
32 | 3.49));
33 |
34 | //################################################################################################
35 | //add dinermenu menu oitems
36 | $dinerMenu->add(new MenuItem("Vegetarian BLT",
37 | "(Fakin’) Bacon with lettuce & tomato on whole wheat", true, 2.99));
38 | $dinerMenu->add(new MenuItem("BLT",
39 | "Bacon with lettuce & tomato on whole wheat", false, 2.99));
40 | $dinerMenu->add(new MenuItem(
41 | "Pasta","Spaghetti with Marinara Sauce, and a slice of sourdough bread",
42 | true, 3.89));
43 |
44 | //################################################################################################
45 | //add dessert menu items
46 | $dessertMenu->add(new MenuItem(
47 | "Apple Pie","Apple pie with a flakey crust, topped with vanilla ice-cream",
48 | true, 1.59));
49 | $dessertMenu->add(new MenuItem(
50 | "Cheesecake","Creamy New York cheesecake, with a chocolate graham crust",
51 | true, 1.99));
52 | $dessertMenu->add(new MenuItem(
53 | "Sorbet","A scoop of raspberry and a scoop of lime",
54 | true, 1.89));
55 |
56 | //add dessert menu to diner menu
57 | $dinerMenu->add($dessertMenu);
58 |
59 | //################################################################################################
60 | //add cafe menu items
61 | $cafeMenu->add(new MenuItem("Veggie Burger and Air Fries",
62 | "Veggie burger on a whole wheat bun, lettuce, tomato, and fries",
63 | true, 3.99));
64 | $cafeMenu->add(new MenuItem("Soup of the day",
65 | "A cup of the soup of the day, with a side salad",
66 | false, 3.69));
67 | $cafeMenu->add(new MenuItem("Burrito",
68 | "A large burrito, with whole pinto beans, salsa, guacamole",
69 | true, 4.29));
70 |
71 |
72 | $waitress = new Waitress($allMenus);
73 |
74 | $waitress->printMenu();
--------------------------------------------------------------------------------
/Composite pattern/README.md:
--------------------------------------------------------------------------------
1 | # Composite pattern
2 | Compose objects into tree structured to request part whole hierarchies, Composite let's clients treat individual objects and compositions of objects uniformly.
3 |
4 | ### Problem
5 | We have restaurant that have many menus one for Breakfast, Dinner and Lunch and there is also a dessert menu and we need to maintain this program so we can have access to add items to submenus and make menus submenu of other menu( Menu Composition :D ).
6 |
7 | ### In the future (we want)
8 | - add more menus.
9 | - nest submenus in a 4 level menus let's say ( MainMenu => Breakfast => Kids Menus => Dessert ).
10 | - have the flexibility of accessing any composed feature using the parent object.
11 |
12 | ### Now pattern talks
13 | - this pattern is most commonly used in the graphics framework.
14 | - use this pattern when dealing with tree structures Anything.
15 | #### UML Diagram
16 | Sorry for the bad quality
17 | 
18 | #### Folder Structure
19 | read the following folder structure and then have a look on the code
20 | ```
21 | ├───Components (Components that holds fake interfaces for our application)
22 | │ MenuComponent.php
23 | │
24 | ├───Entities (Entities that will implement or use the component)
25 | │ Menu.php
26 | │ MenuItem.php
27 | │ Waitress.php
28 | │
29 | ├───Interators (iterators for our components to loop on items after composing objects)
30 | │ CompositeIterator.php
31 | │ MenuComponentsIterator.php
32 | │ NullIterator.php
33 | │
34 | └───Interfaces (simple app interfaces )
35 | IteratorInterface.php
36 | ```
37 |
38 | -- Run `Main.php` and trace the execution to get familiar with the pattern.
--------------------------------------------------------------------------------
/Composite pattern/UML.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aa-ahmed-aa/Design_Pattern/d1640fb645d2f939a633e26db1b6b885c1cb3c5a/Composite pattern/UML.jpg
--------------------------------------------------------------------------------
/Composite pattern/UnsupportedOperationException.php:
--------------------------------------------------------------------------------
1 | description = "Dark Roast.";
11 | }
12 |
13 | function cost()
14 | {
15 | return 0.99;
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/Decorator pattern/Beverages/Decaf.php:
--------------------------------------------------------------------------------
1 | description = "Decaf.";
11 | }
12 |
13 | function cost()
14 | {
15 | return 1.05;
16 | }
17 | }
--------------------------------------------------------------------------------
/Decorator pattern/Beverages/Espresso.php:
--------------------------------------------------------------------------------
1 | description = "Espresso.";
11 | }
12 |
13 | function cost()
14 | {
15 | return 1.99;
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/Decorator pattern/Beverages/HouseBlend.php:
--------------------------------------------------------------------------------
1 | description = "HouseBlend";
18 | }
19 |
20 | function cost()
21 | {
22 | return 0.89;
23 | }
24 | }
--------------------------------------------------------------------------------
/Decorator pattern/Condiments/Mocha.php:
--------------------------------------------------------------------------------
1 | beverage = $beverage;
19 | }
20 |
21 | function getDescription()
22 | {
23 | return $this->beverage->getDescription() . ", Mocha";
24 | }
25 |
26 | function cost()
27 | {
28 | return $this->beverage->cost() + 0.2;
29 | }
30 | }
--------------------------------------------------------------------------------
/Decorator pattern/Condiments/Soy.php:
--------------------------------------------------------------------------------
1 | beverage = $beverage;
20 | }
21 |
22 | function getDescription()
23 | {
24 | return $this->beverage->getDescription() . ", Soy";
25 | }
26 |
27 | function cost()
28 | {
29 | return $this->beverage->cost() + 0.15;
30 | }
31 | }
--------------------------------------------------------------------------------
/Decorator pattern/Condiments/SteamedMilk.php:
--------------------------------------------------------------------------------
1 | beverage = $beverage;
20 | }
21 |
22 | function getDescription()
23 | {
24 | return $this->beverage->getDescription() . ", SteamedMilk";
25 | }
26 |
27 | function cost()
28 | {
29 | return $this->beverage->cost() + 0.1;
30 | }
31 | }
--------------------------------------------------------------------------------
/Decorator pattern/Condiments/Whip.php:
--------------------------------------------------------------------------------
1 | beverage = $beverage;
20 | }
21 |
22 | function getDescription()
23 | {
24 | return $this->beverage->getDescription() . ", Whip";
25 | }
26 |
27 | function cost()
28 | {
29 | return $this->beverage->cost() + 0.1;
30 | }
31 | }
--------------------------------------------------------------------------------
/Decorator pattern/Entities/Beverage.php:
--------------------------------------------------------------------------------
1 | description);
11 | return $this->description;
12 | }
13 |
14 | public abstract function cost();
15 |
16 | }
--------------------------------------------------------------------------------
/Decorator pattern/Entities/CondimentDecorator.php:
--------------------------------------------------------------------------------
1 | getDescription() . " costs " . $beverage->cost() . "\n";
13 |
14 | /** Awesome usage */
15 | $beverage_2 = new DarkRoast();
16 | $beverage_2 = new Mocha($beverage_2);
17 | $beverage_2 = new Mocha($beverage_2);
18 | $beverage_2 = new Whip($beverage_2);
19 |
20 | echo $beverage_2->getDescription() . " costs " . $beverage_2->cost() . "\n";
21 |
22 | $beverage_3 = new HouseBlend();
23 | $beverage_3 = new Soy($beverage_3);
24 | $beverage_3 = new Mocha($beverage_3);
25 | $beverage_3 = new Whip($beverage_3);
26 |
27 | echo $beverage_3->getDescription() . " costs " . $beverage_3->cost() . "\n";
--------------------------------------------------------------------------------
/Decorator pattern/README.md:
--------------------------------------------------------------------------------
1 | # Decorator Pattern (Decorating Objects)
2 | Decorators provide a flexibile alternative to subclassing extending functionality.
3 |
4 | ### Problem
5 | We have a coffee shop called StarBuzz and they have coffee and condiments every list with it's prices:-
6 | ```
7 | Coffee
8 | House Blend 0.89
9 | Dark Roast 0.99
10 | Decaf 1.05
11 | Espresso 1.99
12 | Condiments
13 | Steamed Milk 0.10
14 | Mocha 0.20
15 | Soy 0.15
16 | Whip 0.10
17 | ```
18 | for example the customer might order (Decaf, double Mocha, Whip ) so it costs (1.05 + 2 * 0.20 + 0.10)
19 | we want to maintain this program :).
20 |
21 | ### In the future (we want)
22 | - add other items to the menu.
23 | - add another factor to calculate the price (size for example large , medium, small).
24 |
25 | ### Now pattern talks
26 |
27 | #### UML Diagram
28 | 
29 | #### Folder Structure
30 | read the following folder structure and then have a look on the code
31 | ```
32 | ├───Beverages (holds the beverages for our menu)
33 | │ DarkRoast.php
34 | │ Decaf.php
35 | │ Espresso.php
36 | │ HouseBlend.php
37 | │
38 | ├───Condiments (holds the condiments for our menu)
39 | │ Mocha.php
40 | │ Soy.php
41 | │ SteamedMilk.php
42 | │ Whip.php
43 | │
44 | └───Entities (main entities in the program)
45 | Beverage.php
46 | CondimentDecorator.php
47 | ```
48 |
49 | -- Run `Main.php` and trace the execution to get familiar with the pattern.
--------------------------------------------------------------------------------
/Facade pattern/Components/Amplifier.php:
--------------------------------------------------------------------------------
1 | movie = $movie;
15 | echo "DVD Player playing '$movie' " . PHP_EOL;
16 | }
17 |
18 | public function stop(){
19 | echo "DVD Player stopped '". $this->movie . "'". PHP_EOL;
20 | }
21 |
22 | public function eject(){
23 | echo "DVD Player eject " . PHP_EOL;
24 | }
25 |
26 | public function off(){
27 | echo "DVD Player off " . PHP_EOL;
28 | }
29 | }
--------------------------------------------------------------------------------
/Facade pattern/Components/PopcornPopper.php:
--------------------------------------------------------------------------------
1 | amp = $amp;
36 | $this->tuner = $tuner;
37 | $this->dvd = $dvd;
38 | $this->cd = $cd;
39 | $this->projector = $projector;
40 | $this->screen = $screen;
41 | $this->lights = $lights;
42 | $this->popper = $popper;
43 | }
44 |
45 | public function watchMovie(string $movie){
46 | echo "Get ready to watch a movie..." . PHP_EOL;
47 | $this->popper->on();
48 | $this->popper->pop();
49 | $this->lights->dim(10);
50 | $this->screen->down();
51 | $this->projector->on();
52 | $this->projector->wideScreenMode();
53 | $this->amp->on();
54 | $this->amp->setDvd($this->dvd);
55 | $this->amp->setSurroundSound();
56 | $this->amp->setVolume(5);
57 | $this->dvd->on();
58 | $this->dvd->play($movie);
59 | }
60 |
61 | public function endMovie(){
62 | echo "Shutting movie theater down... " . PHP_EOL;
63 | $this->popper->off();
64 | $this->lights->on();
65 | $this->screen->up();
66 | $this->projector->off();
67 | $this->amp->off();
68 | $this->dvd->stop();
69 | $this->dvd->eject();
70 | $this->dvd->off();
71 | }
72 | }
--------------------------------------------------------------------------------
/Facade pattern/Main.php:
--------------------------------------------------------------------------------
1 | watchMovie("Stranger Things");
30 | echo PHP_EOL;
31 | $homeTheater->endMovie();
--------------------------------------------------------------------------------
/Facade pattern/README.md:
--------------------------------------------------------------------------------
1 | # Facade Pattern
2 | Provides a unified interface to a set of interfaces in a subsystem facade defines a higher-level interface that makes the subsystem easier to use.
3 |
4 | ### Problem
5 | We have a set of devices (amplifier, projector, tunner, dvdplayer, popcorn machine) every device has its own task and we want to add a function to use those devices features.
6 |
7 | ### In the future (we want)
8 | - add more complex tasks that overrides the system tasks without coupling them.
9 |
10 | ### Now pattern talks
11 |
12 | #### UML Diagram
13 | 
14 | #### Folder Structure
15 | read the following folder structure and then have a look on the code
16 | ```
17 | ├───Components ( holds our system main functions )
18 | │ Amplifier.php
19 | │ CdPlayer.php
20 | │ DvdPlayer.php
21 | │ PopcornPopper.php
22 | │ Projector.php
23 | │ Screen.php
24 | │ TheaterLights.php
25 | │ Tuner.php
26 | │
27 | └───Facades ( holds our main facades )
28 | HomeTheaterFacade.php
29 | ```
30 |
31 | -- Run `Main.php` and trace the execution to get familiar with the pattern.
--------------------------------------------------------------------------------
/Factory pattern/Entities/CheesePizza.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Factory pattern/Interfaces/Pizza.php:
--------------------------------------------------------------------------------
1 | factory = $factory;
14 | }
15 |
16 | public function orderPizza( $type )
17 | {
18 | $pizza = $this->factory->createPizza( $type );
19 |
20 | $pizza->prepare();
21 | $pizza->bake();
22 | $pizza->cut();
23 | $pizza->box();
24 |
25 | return $pizza;
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/Factory pattern/Main.php:
--------------------------------------------------------------------------------
1 | orderPizza("pepperoni");
11 |
12 | print "Done.\n";
--------------------------------------------------------------------------------
/Factory pattern/README.md:
--------------------------------------------------------------------------------
1 | # Factory Pattern
2 | Factory pattern divided into two main types (Factory method and Abstract factory), In this pattern i will focus on the difference between the two subset patterns and will code only the factory method.
3 |
4 | ## We need to talk
5 | #### Abstract Factory
6 | Provide an interface creating families of related or dependent objects without specifying their concrete classes.
7 | with the Abstract Factory pattern, a class delegates the responsibility of object instantiation to another object via composition.
8 |
9 | #### Factory Method
10 | Defines an interface for creating an object, but let the subclass decides which class to instantiate Factory Method lets a class defer instantiation to the subclass.
11 | the Factory Method pattern uses inheritance and relies on a subclass to handle the desired object instantiation.
12 |
13 | ###### check out this awesome answer [link](https://stackoverflow.com/q/5739611/5701752)
14 |
15 | ### Problem
16 | We have a pizza store this store has Cheese, Veggie, Clam, Pepperoni Pizza except in
17 | some little details and they have the same process for every pizza prepare(), bake(), cut(), box().
18 |
19 | ### In the future (we want)
20 | - Add types of pizzas.
21 | - Add stores and every store has it's own types of pizzas.
22 |
23 | ### Now pattern talks
24 |
25 | #### UML Diagram
26 | 
27 | #### Folder Structure
28 | read the following folder structure and then have a look on the code
29 | ```
30 | ├───Entities (holds the types of the pizzas)
31 | │ CheesePizza.php
32 | │ ClamPizza.php
33 | │ PepperoniPizza.php
34 | │ VeggiePizza.php
35 | │
36 | ├───Factories (our pizza factory)
37 | │ SimpleFactory.php (our factory method pattern applied here)
38 | │
39 | └───Interfaces
40 | Pizza.php
41 | PizzaStore.php (we might apply the abstract factory here in the future if we added more branches to our store)
42 | ```
43 |
44 | -- Run `Main.php` and trace the execution to get familiar with the pattern.
--------------------------------------------------------------------------------
/Iterator pattern/Entities/DinerMenu.php:
--------------------------------------------------------------------------------
1 | addItem("Vegetarian BLT", "(Fakin’) Bacon with lettuce & tomato on whole wheat", true, 2.99);
17 | $this->addItem("BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99);
18 | $this->addItem("Soup of the day", "Soup of the day, with a side of potato salad", false, 3.29);
19 | $this->addItem("Hotdog", "A hot dog, with saurkraut, relish, onions, topped with cheese", false, 3.05);
20 | $this->addItem("Steamed Veggies and Brown Rice", "Steamed vegetables over brown rice", true, 3.99);
21 | $this->addItem("Pasta", "Spaghetti with Marinara Sauce and a slice of sourdough bread", false, 3.89);
22 | }
23 |
24 | public function addItem( $name, $description, $vegetarian, $price )
25 | {
26 | $item = new MenuItem($name, $description, $vegetarian, $price);
27 | array_push($this->menuItems, $item);
28 | }
29 |
30 | public function createIterator()
31 | {
32 | return new DinerMenuIterator($this->menuItems);
33 | }
34 |
35 | public function getName()
36 | {
37 | return $this->name;
38 | }
39 | }
--------------------------------------------------------------------------------
/Iterator pattern/Entities/MenuItem.php:
--------------------------------------------------------------------------------
1 | name = $name;
16 | $this->description = $description;
17 | $this->vegetarian = $vegetarian;
18 | $this->price = $price;
19 | }
20 |
21 | public function getName()
22 | {
23 | return $this->name;
24 | }
25 |
26 | public function getDescription()
27 | {
28 | return $this->description;
29 | }
30 |
31 | public function getPrice()
32 | {
33 | return $this->price;
34 | }
35 |
36 | public function isVegetarian()
37 | {
38 | return $this->vegetarian;
39 | }
40 | }
--------------------------------------------------------------------------------
/Iterator pattern/Entities/PancakeHouseMenu.php:
--------------------------------------------------------------------------------
1 | addItem("K&B’s Pancake Breakfast","Pancakes with scrambled eggs, and toast ",true,2.99);
17 | $this->addItem("Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false, 2.99);
18 | $this->addItem("Blueberry Pancakes", "Pancakes made with fresh blueberries", true, 3.49);
19 | $this->addItem("Waffles", "Waffles, with your choice of blueberries or strawberries", true, 3.59);
20 | }
21 |
22 | public function addItem( $name, $description, $vegetarian, $price )
23 | {
24 | $item = new MenuItem($name, $description, $vegetarian, $price);
25 | array_push($this->menuItems, $item);
26 | }
27 |
28 | public function createIterator()
29 | {
30 | return new PancakeHouseMenuIterator($this->menuItems);
31 | }
32 |
33 | public function getName()
34 | {
35 | return $this->name;
36 | }
37 | }
--------------------------------------------------------------------------------
/Iterator pattern/Entities/Waitress.php:
--------------------------------------------------------------------------------
1 | panCakeHouseMenu = $pancakeHouseMenu;
16 | $this->dinerMenu = $dinerMenu;
17 | }
18 |
19 | public function printMenu()
20 | {
21 | $panCakeIterator = $this->panCakeHouseMenu->createIterator();
22 | $dinerMenu = $this->dinerMenu->createIterator();
23 | print "\nMenu\n-----------------\nBreakFast\n";
24 | $this->printSpecificMenu( $panCakeIterator );
25 | print "\nLunch\n";
26 | $this->printSpecificMenu( $dinerMenu );
27 | }
28 |
29 | private function printSpecificMenu(Iterator $iterator)
30 | {
31 | while( $iterator->hasNext() )
32 | {
33 | $menuItem = $iterator->next();
34 | print $menuItem->getName() . ", " . $menuItem->getPrice() . " -- " . $menuItem->getDescription() . "\n";
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/Iterator pattern/Interfaces/Iterator.php:
--------------------------------------------------------------------------------
1 | items = $items;
16 | }
17 |
18 | public function next()
19 | {
20 | return $this->items[$this->position++];
21 | }
22 |
23 | public function hasNext()
24 | {
25 | if($this->position >= count($this->items))
26 | return false;
27 | return true;
28 | }
29 | }
--------------------------------------------------------------------------------
/Iterator pattern/Iterators/PancakeHouseMenuIterator.php:
--------------------------------------------------------------------------------
1 | menuItems = $array;
15 | }
16 |
17 | public function next(){
18 | return $this->menuItems[$this->index++];
19 | }
20 |
21 | public function hasNext(){
22 | if($this->index >= count($this->menuItems))
23 | return false;
24 | return true;
25 | }
26 | }
--------------------------------------------------------------------------------
/Iterator pattern/Main.php:
--------------------------------------------------------------------------------
1 | printMenu();
--------------------------------------------------------------------------------
/Iterator pattern/README.md:
--------------------------------------------------------------------------------
1 | # Iterator Pattern
2 | Provide a way to access of an aggregation object sequentially without exposing it's underlying representation.
3 |
4 | ## Scenario
5 | we have two menus one for breakfast and another for dinner we want to iterate over those two menus without writing a duplicated code.
6 |
7 | ### In the future (we want)
8 | - add more shared features between those menus(or what kind of object they were).
9 |
10 | ### Now pattern talks
11 |
12 | #### UML Diagram
13 | 
14 | #### Folder Structure
15 | read the following folder structure and then have a look on the code
16 | ```
17 | ├───Entities (holds the entities like the pancake, waitress and dinner)
18 | │ DinerMenu.php
19 | │ MenuItem.php
20 | │ PancakeHouseMenu.php
21 | │ Waitress.php
22 | │
23 | ├───Interfaces (static interfaces used in our application most important is the iterator)
24 | │ Iterator.php
25 | │ Menu.php
26 | │
27 | └───Iterators (implemented iterators used for the pancake and dinner)
28 | DinerMenuIterator.php
29 | PancakeHouseMenuIterator.php
30 | ```
31 |
32 | -- Run `Main.php` and trace the execution to get familiar with the pattern.
--------------------------------------------------------------------------------
/Observer pattern/Entities/CurrentConditionsDisplay.php:
--------------------------------------------------------------------------------
1 | weatherData = $weatherData;
17 | $weatherData->registerObserver( $this );
18 | }
19 |
20 | public function update($temp, $humidity, $pressure)
21 | {
22 | $this->temperature = $temp;
23 | $this->humidity = $humidity;
24 | $this->display();
25 | }
26 |
27 | public function display()
28 | {
29 | echo "Current conditions: $this->temperature F and $this->humidity % humidity.\n";
30 | }
31 | }
--------------------------------------------------------------------------------
/Observer pattern/Entities/ForecastDisplay.php:
--------------------------------------------------------------------------------
1 | weatherData = $weatherData;
17 | $weatherData->registerObserver( $this );
18 | }
19 |
20 | public function update($temp, $humidity, $pressure)
21 | {
22 | $this->temperature = $temp;
23 | $this->humidity = $humidity;
24 | $this->display();
25 | }
26 |
27 | public function display()
28 | {
29 | echo "Forecast conditions: $this->temperature FCo and $this->humidity % humidity.\n";
30 | }
31 | }
--------------------------------------------------------------------------------
/Observer pattern/Entities/StatisticsDisplay.php:
--------------------------------------------------------------------------------
1 | weatherData = $weatherData;
17 | $weatherData->registerObserver( $this );
18 | }
19 |
20 | public function update($temp, $humidity, $pressure)
21 | {
22 | $this->temperature = $temp;
23 | $this->humidity = $humidity;
24 | $this->display();
25 | }
26 |
27 | public function display()
28 | {
29 | echo "Statistics condition: $this->temperature Co and $this->humidity % humidity.\n";
30 | }
31 | }
--------------------------------------------------------------------------------
/Observer pattern/Interfaces/DisplayElement.php:
--------------------------------------------------------------------------------
1 | setMeasurements(80, 45, 29);
16 | echo "------------------------------------------\n";
17 | $weatherData->setMeasurements(92, 20, 21);
18 | echo "------------------------------------------\n";
19 | $weatherData->setMeasurements(85, 29, 15);
20 |
21 |
--------------------------------------------------------------------------------
/Observer pattern/Objects/WeatherData.php:
--------------------------------------------------------------------------------
1 | observers = [];
17 | }
18 |
19 | public function registerObserver( $o )
20 | {
21 | $this->observers[] = $o;
22 | }
23 |
24 | public function removeObserver( $o )
25 | {
26 | if (($key = array_search( $o, $this->observers ) ) !== false) {
27 | unset($this->observers[$key]);
28 | }
29 | }
30 |
31 | public function notifyObservers()
32 | {
33 | for( $i = 0 ; $i < count($this->observers) ; $i++ )
34 | {
35 | $this->observers[$i]->update( $this->temperature, $this->humidity, $this->pressure );
36 | }
37 | }
38 |
39 | public function measurementsChange()
40 | {
41 | $this->notifyObservers();
42 | }
43 |
44 | public function setMeasurements($temperature, $humidity, $pressure)
45 | {
46 | $this->temperature = $temperature;
47 | $this->humidity = $humidity;
48 | $this->pressure = $pressure;
49 | $this->measurementsChange();
50 | }
51 |
52 | }
--------------------------------------------------------------------------------
/Observer pattern/README.md:
--------------------------------------------------------------------------------
1 | # Observer Pattern (Keeping your objects in the know)
2 | Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
3 | you may see this pattern used alot in the front-end framework because it needs to eep track of data synced to the UI.
4 |
5 |
6 | ### Problem
7 | We have a weather station predicts the weather and display the results to many other places it displays the weather status to forecast, statistics ....etc we need to keep track of the weather status for all formats.
8 |
9 | ### In the future (we want)
10 | - add display for other ways(types) for example TV news weather.
11 | - perform some operations before we update weather for specific form :
12 | imagine this scenario the weather station needs to send weather status to army but before it is been sent we want to notify the military stations in the area first.
13 |
14 | ### Now pattern talks
15 |
16 | #### UML Diagram
17 | 
18 | #### Folder Structure
19 | read the following folder structure and then have a look on the code
20 | ```
21 | ├───Entities (holds the entities that will implement the weather status in some way)
22 | │ CurrentConditionsDisplay.php
23 | │ ForecastDisplay.php
24 | │ StatisticsDisplay.php
25 | │
26 | ├───Interfaces (holds all of the interfaces for our program)
27 | │ DisplayElement.php
28 | │ Observer.php
29 | │ Subject.php
30 | │
31 | └───Objects (holds our main feature to keep track of the weather)
32 | WeatherData.php
33 | ```
34 |
35 | -- Run `Main.php` and trace the execution to get familiar with the pattern.
--------------------------------------------------------------------------------
/Proxy pattern/Entities/RealFile.php:
--------------------------------------------------------------------------------
1 | fileName = $fileName;
15 |
16 | $this->load($fileName);
17 | }
18 |
19 | public function load(string $fileName)
20 | {
21 | print "Loading '$fileName'...\n";
22 |
23 | $openedFile = fopen($fileName, "r");
24 |
25 | $this->content = fread($openedFile, filesize($this->fileName));
26 | }
27 |
28 | public function display()
29 | {
30 | print $this->content;
31 | }
32 | }
--------------------------------------------------------------------------------
/Proxy pattern/Interfaces/File.php:
--------------------------------------------------------------------------------
1 | display();
8 |
9 | print "\n \n File already loaded from disk before, thus just display it now!\n";
10 | $image->display();
--------------------------------------------------------------------------------
/Proxy pattern/Proxies/ProxyFile.php:
--------------------------------------------------------------------------------
1 | fileName = $fileName;
16 | }
17 |
18 | /**
19 | * Proxy pattern
20 | **/
21 | public function display()
22 | {
23 | if ($this->realFile == null)
24 | $this->realFile = new RealFile($this->fileName);
25 |
26 | print $this->realFile->display();
27 | }
28 | }
--------------------------------------------------------------------------------
/Proxy pattern/README.md:
--------------------------------------------------------------------------------
1 | # Proxy Pattern
2 | Provide a surrogate or placeholder for another object to control access to it
3 |
4 | ##### Note
5 | this pattern here is not from the book (HFDP) it is based on [this blog](https://medium.com/@devlob/proxy-design-pattern-to-speed-up-your-applications-2416816493d)
6 |
7 | ### Problem
8 | Read-write operations will always be time consuming, since we directly access the disk and that takes some time, so you can write a code that minimises the amount of times that we have to access a central container, like the hard disk or the database, which they tend to be very slow compared to RAM
9 |
10 | ### In the future (we want)
11 | - add more behaviors between proxies.
12 | - Not repeating ( coupling ) actions so performance enhancement
13 |
14 | ### Now pattern talks
15 |
16 | #### Folder Structure
17 | read the following folder structure and then have a look on the code
18 | ```
19 | ├───Entities (Behaviors you will use in the proxy)
20 | │ RealFile.php
21 | │
22 | ├───Interfaces (interfaces that the proxy and the behaviors should implement)
23 | │ File.php
24 | │
25 | └───Proxies (Proxies means owner of the entities and it can access and use them)
26 | ProxyFile.php
27 | ```
28 |
29 | -- Run `Main.php` and trace the execution to get familiar with the pattern.
--------------------------------------------------------------------------------
/Proxy pattern/test.txt:
--------------------------------------------------------------------------------
1 | Ahmed Khaled mohamed
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Design_Pattern
2 | Php code for [Head First Design Pattern](https://www.amazon.com/Head-First-Design-Patterns-Brain-Friendly/dp/0596007124) with the power of namespaces also this repo is open for any other patterns in the future.
3 |
4 | ## Usage
5 | Run `composer install` to generate the psr-4 autoloader.
6 |
7 | ## Patterns
8 | + [Strategy pattern](https://github.com/aa-ahmed-aa/Design_Pattern/tree/master/Strategy%20pattern).
9 | + [Observer Pattern (Keeping your objects in the know)](https://github.com/aa-ahmed-aa/Design_Pattern/tree/master/Observer%20pattern).
10 | + [Decorator Pattern (Decorating Objects)](https://github.com/aa-ahmed-aa/Design_Pattern/tree/master/Decorator%20pattern).
11 | + [Factory Pattern (Backing with oo Goodness)](https://github.com/aa-ahmed-aa/Design_Pattern/tree/master/Factory%20pattern).
12 | + [Singleton Pattern (One of a kind object)](https://github.com/aa-ahmed-aa/Design_Pattern/tree/master/Singleton%20pattern).
13 | + [Command Pattern (Encapsulating Invocation)](https://github.com/aa-ahmed-aa/Design_Pattern/tree/master/Command%20pattern).
14 | + [Adapter Pattern](https://github.com/aa-ahmed-aa/Design_Pattern/tree/master/Adapter%20pattern).
15 | + [Facade Pattern](https://github.com/aa-ahmed-aa/Design_Pattern/tree/master/Facade%20pattern).
16 | + [Template Method Pattern (Encapsulating Algorithms)](https://github.com/aa-ahmed-aa/Design_Pattern/tree/master/Template%20Method%20pattern).
17 | + [Iterator Pattern](https://github.com/aa-ahmed-aa/Design_Pattern/tree/master/Iterator%20pattern).
18 | + [Composite Pattern](https://github.com/aa-ahmed-aa/Design_Pattern/tree/master/Composite%20pattern).
19 | + [Proxy Pattern](https://github.com/aa-ahmed-aa/Design_Pattern/tree/master/Proxy%20pattern).
20 | + [State Pattern](https://github.com/aa-ahmed-aa/Design_Pattern/tree/master/State%20pattern).
--------------------------------------------------------------------------------
/Singleton pattern/ChocolateBoiler.php:
--------------------------------------------------------------------------------
1 | empty = true;
14 | $this->boiled = false;
15 | }
16 |
17 | public function fill()
18 | {
19 | if( $this->isEmpty() )
20 | {
21 | $this->empty = false;
22 | $this->boiled = false;
23 | // fill the boiled with a milk/chocolate mixture
24 | print "fill the boiled with a milk/chocolate mixture......\n";
25 | }
26 | }
27 |
28 | public function drain()
29 | {
30 | if( ! $this->isEmpty() && $this->isBoiled() )
31 | {
32 | print "drain the boiled milk and chocolate....\n";
33 | $this->empty = true;
34 | }
35 | }
36 |
37 | public function boil()
38 | {
39 | if( ! $this->isEmpty() && ! $this->isBoiled() )
40 | {
41 | print "bring the contents to a boil.....\n";
42 | $this->boiled = true;
43 | }
44 | }
45 |
46 | public function isEmpty()
47 | {
48 | return $this->empty;
49 | }
50 |
51 | public function isBoiled()
52 | {
53 | return $this->boiled;
54 | }
55 | }
--------------------------------------------------------------------------------
/Singleton pattern/README.md:
--------------------------------------------------------------------------------
1 | # Singleton Pattern
2 | Ensure that a class has one instance and provide a global point of access to it ,we can say that this pattern is our ticket to creating one-of-a-kind objects for which there is only one instance.
3 |
4 | ### Problem
5 | We have a chocolate boiler that mix up the milk and chocolate and keep boiler boiling and filling
6 |
7 | ### In the future (we want)
8 | - at anytime we want to check for boiling and filled instance.
9 |
10 | ### Now pattern talks
11 |
12 | #### UML Diagram
13 | 
14 | #### Folder Structure
15 | This is the simplest file till now, the folder structure is only one file.Simple job here is to fill and check the boiling variable of the chocolate boiler.
--------------------------------------------------------------------------------
/State pattern/Entities/GumballMachine.php:
--------------------------------------------------------------------------------
1 | soldOutState = new SoldoutState($this);
25 | $this->noQuarterState = new NoQuarterState($this);
26 | $this->hasQuarterState = new HasQuarterState($this);
27 | $this->soldState = new SoldState($this);
28 |
29 | $this->count = $numberGumballs;
30 | if( $numberGumballs > 0 )
31 | {
32 | $this->state = $this->noQuarterState;
33 | }else{
34 | $this->state = $this->soldOutState;
35 | }
36 | }
37 |
38 | public function insertQuarter()
39 | {
40 | $this->state->insertQuarter();
41 | }
42 |
43 | public function ejectQuarter()
44 | {
45 | $this->state->ejectQuarter();
46 | }
47 |
48 | public function turnCrank()
49 | {
50 | $this->state->turnCrank();
51 | $this->state->dispense();
52 | }
53 |
54 | public function setState( $state )
55 | {
56 | $this->state = $state;
57 | }
58 |
59 | public function releaseBall()
60 | {
61 | print "A gumball comes rolling out the slot...";
62 | if( $this->count != 0 )
63 | {
64 | $this->count = $this->count -1;
65 | }
66 | }
67 |
68 | //getters for states
69 |
70 | /**
71 | * @return HasQuarterState
72 | */
73 | public function getHasQuarterState()
74 | {
75 | return $this->hasQuarterState;
76 | }
77 |
78 | /**
79 | * @return NoQuarterState
80 | */
81 | public function getNoQuarterState()
82 | {
83 | return $this->noQuarterState;
84 | }
85 |
86 | /**
87 | * @return SoldoutState
88 | */
89 | public function getSoldOutState()
90 | {
91 | return $this->soldOutState;
92 | }
93 |
94 | /**
95 | * @return int
96 | */
97 | public function getCount()
98 | {
99 | return $this->count;
100 | }
101 |
102 | /**
103 | * @return soldState
104 | */
105 | public function getSoldState()
106 | {
107 | return $this->soldState;
108 | }
109 |
110 | /**
111 | * @return SoldoutState
112 | */
113 | public function getState()
114 | {
115 | return $this->state;
116 | }
117 |
118 | /**
119 | * @return mixed
120 | */
121 | public function getWinnerState()
122 | {
123 | return $this->winnerState;
124 | }
125 | }
--------------------------------------------------------------------------------
/State pattern/Interfaces/State.php:
--------------------------------------------------------------------------------
1 | insertQuarter();
9 | $gumballMachine->turnCrank();
10 |
11 | $gumballMachine->insertQuarter();
12 | $gumballMachine->turnCrank();
13 | $gumballMachine->insertQuarter();
14 | $gumballMachine->turnCrank();
--------------------------------------------------------------------------------
/State pattern/README.md:
--------------------------------------------------------------------------------
1 | # State Pattern
2 | Allow an object to alter its behavior when its internal state changes the object will appear to change its class.
3 |
4 | ### Problem
5 | We have a gumball machine and the machine have many states to manage (insert, turnCrank, and dispense) write code that manages this problem
6 |
7 | ### In the future (we want)
8 | - add more states to the machine.
9 |
10 | ### Now pattern talks
11 |
12 | #### UML Diagram
13 | 
14 | #### Folder Structure
15 | read the following folder structure and then have a look on the code
16 | ```
17 | ├───Entities (holds the entities of the application)
18 | │ GumballMachine.php
19 | │
20 | ├───Interfaces (holds the app interfaces)
21 | │ State.php
22 | │
23 | └───States (application statuses)
24 | HasQuarterState.php
25 | NoQuarterState.php
26 | SoldoutState.php
27 | SoldState.php
28 | WinnerState.php
29 | ```
30 |
31 | -- Run `Main.php` and trace the execution to get familiar with the pattern.
--------------------------------------------------------------------------------
/State pattern/States/HasQuarterState.php:
--------------------------------------------------------------------------------
1 | gumballMachine = $gumballMachine;
17 | $this->randomWinner = rand(0,999);
18 | }
19 |
20 | public function insertQuarter()
21 | {
22 | print "You can't insert another quarter...\n";
23 | }
24 |
25 | public function ejectQuarter()
26 | {
27 | print "Quarter returned...\n";
28 | $this->gumballMachine->setState( $this->gumballMachine->getNoQuarterState() );
29 | }
30 |
31 | public function turnCrank()
32 | {
33 | print "You turned...\n";
34 |
35 | if( ($this->randomWinner == 10) && ($this->gumballMachine->getCount() > 1) )
36 | {
37 | $this->gumballMachine->setState( $this->gumballMachine->getWinnerState() );
38 | } else {
39 | $this->randomWinner = rand(0,999);
40 | $this->gumballMachine->setState( $this->gumballMachine->getSoldState() );
41 | }
42 |
43 | }
44 |
45 | public function dispense()
46 | {
47 | print "No gumball dispense...\n";
48 | }
49 | }
--------------------------------------------------------------------------------
/State pattern/States/NoQuarterState.php:
--------------------------------------------------------------------------------
1 | gameballMachine = $gameballMachine;
16 | }
17 |
18 | public function insertQuarter()
19 | {
20 | print "You inserted a quarter...\n";
21 | $this->gameballMachine->setState( $this->gameballMachine->getHasQuarterState() );
22 | }
23 |
24 | public function ejectQuarter()
25 | {
26 | print "You haven't inserted quarter...\n";
27 | }
28 |
29 | public function turnCrank()
30 | {
31 | print "You turned, but there's no quarter...\n";
32 | }
33 |
34 | public function dispense()
35 | {
36 | print "You need to pay first...\n";
37 | }
38 | }
--------------------------------------------------------------------------------
/State pattern/States/SoldState.php:
--------------------------------------------------------------------------------
1 | gumballMachine = $gumballMachine;
16 | }
17 |
18 | public function insertQuarter()
19 | {
20 | print "Please wait, we are already giving you a gumball\n";
21 | }
22 |
23 | public function ejectQuarter()
24 | {
25 | print "Sorry, you already turned the crank\n";
26 | }
27 |
28 | public function turnCrank()
29 | {
30 | print "Turning twice doesn't get you another gumball!\n";
31 | }
32 |
33 | public function dispense()
34 | {
35 | $this->gumballMachine->releaseBall();
36 | if( $this->gumballMachine->getCount() > 0 )
37 | {
38 | $this->gumballMachine->setState( $this->gumballMachine->getNoQuarterState() );
39 | } else {
40 | print "Ooops, out of gumballs!!\n";
41 | $this->gumballMachine->setState( $this->gumballMachine->getSoldOutState() );
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/State pattern/States/SoldoutState.php:
--------------------------------------------------------------------------------
1 | gumballMachine = $gumballMachine;
16 | }
17 |
18 | public function insertQuarter()
19 | {
20 | echo "You can't insert a quarter , the machine is sold out\n";
21 | }
22 |
23 | public function ejectQuarter()
24 | {
25 | echo "You can't eject, You haven't inserted a quarter yet\n";
26 | }
27 |
28 | public function turnCrank()
29 | {
30 | echo "You turned, but there are no gumballs\n";
31 | }
32 |
33 | public function dispense()
34 | {
35 | echo "No gumball dispensed \n";
36 | }
37 | }
--------------------------------------------------------------------------------
/State pattern/States/WinnerState.php:
--------------------------------------------------------------------------------
1 | gumballMachine = $gumballMachine;
17 | }
18 |
19 | public function insertQuarter()
20 | {
21 | print "Please wait, we are already giving you a gumball\n";
22 | }
23 |
24 | public function ejectQuarter()
25 | {
26 | print "Sorry, you already turned the crank\n";
27 | }
28 |
29 | public function turnCrank()
30 | {
31 | print "Turning twice doesn't get you another gumball!\n";
32 | }
33 |
34 | public function dispense()
35 | {
36 | $this->gumballMachine->releaseBall();
37 | if( $this->gumballMachine->getCount() == 0 )
38 | {
39 | $this->gumballMachine->setState( $this->gumballMachine->getSoldOutState() );
40 | } else {
41 | $this->gumballMachine->releaseBall();
42 | print "You are a WINNER! you got two gumballs for your quarter.\n";
43 | if($this->gumballMachine->getCount() > 0)
44 | {
45 | $this->gumballMachine->setState( $this->gumballMachine->getNoQuarterState() );
46 | } else {
47 | print "Oops, out of gumballs!!\n";
48 | $this->gumballMachine->setState( $this->gumballMachine->getSoldOutState() );
49 | }
50 | }
51 | }
52 |
53 | }
--------------------------------------------------------------------------------
/Strategy pattern/Behaviors/FlyBehavior.php:
--------------------------------------------------------------------------------
1 | display();
10 | $rubberDuck->performQuack();
11 | $rubberDuck->performFly();
12 |
13 | echo "-----------------------";
14 |
15 | $rubberDuck = new MallardDuck();
16 | $rubberDuck->display();
17 | $rubberDuck->performQuack();
18 | $rubberDuck->performFly();
--------------------------------------------------------------------------------
/Strategy pattern/Objects/MallardDuck.php:
--------------------------------------------------------------------------------
1 | setFlyBehavior( new FlyNoWay() );
16 | $this->setQuackBehavior( new Squack() );
17 | }
18 |
19 | public function display()
20 | {
21 | echo "i'm a MallardDuck.\n";
22 | }
23 | }
--------------------------------------------------------------------------------
/Strategy pattern/Objects/RubberDuck.php:
--------------------------------------------------------------------------------
1 | setflyBehavior( new FlyNoWay() );
13 | $this->setQuackBehavior( new MuteQuack() );
14 | }
15 |
16 | public function display()
17 | {
18 | echo "i'm a RubberDuck\n";
19 | }
20 | }
--------------------------------------------------------------------------------
/Strategy pattern/README.md:
--------------------------------------------------------------------------------
1 | # Strategy Pattern
2 | Defines a family of algorithms ,encapsulates each one and makes them interchangable. strategy lets the algorithm vary independently
3 |
4 | ### Problem
5 | we have a punch of ducks (MallardDuck, rubberduck ,...etc) and we want to write a program to describe each duck according to one of two features **can fly or not ?** and **can quack or not ?**.
6 |
7 |
8 | ### In the future (we want)
9 | - add more animals to the types.
10 | - add more features to every animal type.
11 | - share common features between animals.
12 |
13 | ### Now pattern talks
14 |
15 | #### UML Diagram
16 | 
17 | #### Folder Structure
18 | read the following folder structure and then have a look on the code
19 | ```
20 | ├───Behaviors ------ (holds the Main behaviors and sub behavior)
21 | │ │ FlyBehavior.php (Main Behaviors)
22 | │ │ QuackBehavior.php
23 | │ │
24 | │ ├───FlyBehaviors ------ (holds sub behaviors of the fly)
25 | │ │ FlyNoWay.php
26 | │ │ FlyRocketPowered.php
27 | │ │ FlyWithWings.php
28 | │ │
29 | │ └───QuackBehaviors
30 | │ MuteQuack.php
31 | │ Quack.php
32 | │ Squack.php
33 | │
34 | ├───Objects ------ (holds the types of every single duck)
35 | │ MallardDuck.php
36 | │ RubberDuck.php
37 | │
38 | └───Types ------ (holds the base types)
39 | Duck.php
40 | ```
41 |
42 | -- Run `Main.php` and trace the execution to get familiar with the pattern.
--------------------------------------------------------------------------------
/Strategy pattern/Types/Duck.php:
--------------------------------------------------------------------------------
1 | flyBehavior = $fb;
17 | $this->quackBehavior = $qb;
18 | }
19 |
20 | public function setFlyBehavior($fb)
21 | {
22 | $this->flyBehavior = $fb;
23 | }
24 |
25 | public function setQuackBehavior($qb)
26 | {
27 | $this->quackBehavior = $qb;
28 | }
29 |
30 | public function performQuack()
31 | {
32 | $this->quackBehavior->quack();
33 | }
34 |
35 | public function performFly()
36 | {
37 | $this->flyBehavior->fly();
38 | }
39 |
40 | /**
41 | * Template for any future behavior
42 | */
43 | public function performAnyThing()
44 | {
45 | // $this->AnyThingBehavior.AnyThing();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Template Method pattern/Entities/Coffee.php:
--------------------------------------------------------------------------------
1 | prepareRecipe();
12 |
13 | print "Making coffee...\n";
14 | $coffee->prepareRecipe();
15 |
16 |
--------------------------------------------------------------------------------
/Template Method pattern/README.md:
--------------------------------------------------------------------------------
1 | # Template Method Pattern (Encapsulating Algorithms)
2 | Define the skeleton of an algorithm in an operation, deferring some steps to subclasses.Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
3 |
4 | ### Problem
5 | We have two types of drinks(tea, coffee) that needs to be prepared from a recipe and those drinks have some steps on common
6 |
7 |
8 | ### In the future (we want)
9 | - add drinks that shares recipe steps .
10 | - control the algorithm of the template .
11 |
12 |
13 | ### Now pattern talks
14 |
15 | #### Folder Structure
16 | read the following folder structure and then have a look on the code
17 | ```
18 | ├───Entities (holds our entities tea,coffeee)
19 | │ Coffee.php
20 | │ Tea.php
21 | │
22 | └───Templates (holds the abstract tempates for our algorithm)
23 | CaffeineBeverage.php
24 | ```
25 |
26 | -- Run `Main.php` and trace the execution to get familiar with the pattern.
--------------------------------------------------------------------------------
/Template Method pattern/Templates/CaffeineBeverage.php:
--------------------------------------------------------------------------------
1 | boilWater();
11 | $this->brew();
12 | $this->pourInCup();
13 | if( $this->customerWantsCondiments() )
14 | {
15 | $this->addCondiments();
16 | }
17 | }
18 |
19 | abstract function brew();
20 |
21 | abstract function addCondiments();
22 |
23 | public function boilWater()
24 | {
25 | print "Boiling water...\n";
26 | }
27 |
28 | public function pourInCup()
29 | {
30 | print "Pouring in cup...\n";
31 | }
32 |
33 | public function customerWantsCondiments()
34 | {
35 | return true;
36 | }
37 | }
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "autoload": {
3 | "psr-4": {
4 | "Strategy\\" : "Strategy pattern/",
5 | "ObserverPattern\\" : "Observer pattern/",
6 | "Decorator\\" : "Decorator pattern/",
7 | "Factory\\" : "Factory pattern/",
8 | "Singleton\\" : "Singleton pattern/",
9 | "Command\\" : "Command pattern/",
10 | "Adapter\\" : "Adapter pattern/",
11 | "Facade\\" : "Facade pattern/",
12 | "TemplateMethod\\" : "Template Method pattern/",
13 | "Iterator\\" : "Iterator pattern/",
14 | "Composite\\" : "Composite pattern/",
15 | "Proxy\\": "Proxy pattern/",
16 | "State\\" : "State pattern/"
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------