├── Behavioral └── Chain Of Responsibility │ ├── ReadMe.md │ └── php-example │ ├── .gitignore │ ├── ReadMe.md │ ├── composer.json │ ├── composer.lock │ ├── src │ ├── Contracts │ │ └── Handler.php │ ├── Entity │ │ ├── Car.php │ │ └── Person.php │ └── Handlers │ │ ├── AbstractHandler.php │ │ ├── CarsHandler.php │ │ └── PeopleHandler.php │ └── tests │ └── index.php └── ReadMe.md /Behavioral/Chain Of Responsibility/ReadMe.md: -------------------------------------------------------------------------------- 1 | # Chain of Responsibility 2 | 3 | is behavioral design pattern that allows passing a request along the chain of potential handlers until one of them handles the request. 4 | 5 | ### Problem: 6 | 7 | Imagine that you are working on some validation system that needs to validate some kind of information lets say mobile numbers for example, you are required to validate the numbers with different 3rd party API based on the phone number country. 8 |
9 | So, you have a client that gets a phone number and you need to know which handler should handle this phone number to use?! 10 |
11 | Give it sometime to think about the possible solutions to solve this problem. 12 | 13 | ### Solution: 14 | So, the best solution for this is to have something called a chain so you give the chain the phone number and the first handler in the chain check can I inspect this phone number YES so apply the logic and if NO pass the phone number to the next handler in the chain...etc. 15 |
16 | That is in very basic words the COR pattern how it works. 17 | 18 | ### Applicability: 19 | 20 | * When your application expected to process different requests in different ways. 21 | * When it is required to execute several handlers in specific order. 22 | 23 | ### Pros & Cons 24 | #### Pros: 25 | * Control the order of the request handling. 26 | * Single Responsibility Priciple. 27 | * Open/Closed Principle. 28 | #### Cons: 29 | * Some requests may end up unhandled. 30 | 31 | 32 | ### Dive into: 33 | * [Real World Example](https://www.php-fig.org/psr/psr-15/) 34 | * [Chain of responsibility pattern](https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern) 35 | * https://sourcemaking.com/design_patterns/chain_of_responsibility 36 | * https://refactoring.guru/design-patterns/chain-of-responsibility -------------------------------------------------------------------------------- /Behavioral/Chain Of Responsibility/php-example/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | vendor -------------------------------------------------------------------------------- /Behavioral/Chain Of Responsibility/php-example/ReadMe.md: -------------------------------------------------------------------------------- 1 | ### Requirements: 2 | * PHP 7.4 3 | 4 | ### How to run: 5 | * In your terminal go to the project folder then run: 6 | ```cmd 7 | $ php tests/index.php 8 | ``` -------------------------------------------------------------------------------- /Behavioral/Chain Of Responsibility/php-example/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "behavioral/cor", 3 | "description": "Simple example for the Chain Of Responsibility design pattern", 4 | "type": "project", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Ahmed Raafat", 9 | "email": "ahmed.raafat1412@gmail.com", 10 | "homepage": "https://github.com/AhmedRaafat14/" 11 | } 12 | ], 13 | "require": { 14 | "php": "^7.4" 15 | }, 16 | "minimum-stability": "stable", 17 | "autoload": { 18 | "psr-4": { 19 | "Behavioral\\COR\\": "src" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Behavioral/Chain Of Responsibility/php-example/composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "b751a59a63d19f8efe8a4f133138540a", 8 | "packages": [], 9 | "packages-dev": [], 10 | "aliases": [], 11 | "minimum-stability": "stable", 12 | "stability-flags": [], 13 | "prefer-stable": false, 14 | "prefer-lowest": false, 15 | "platform": { 16 | "php": "^7.4" 17 | }, 18 | "platform-dev": [] 19 | } 20 | -------------------------------------------------------------------------------- /Behavioral/Chain Of Responsibility/php-example/src/Contracts/Handler.php: -------------------------------------------------------------------------------- 1 | model = $model; 27 | return $this; 28 | } 29 | 30 | /** 31 | * @return string 32 | */ 33 | public function getModel(): string 34 | { 35 | return $this->model; 36 | } 37 | 38 | /** 39 | * @param string $manufacturer 40 | * @return Car 41 | */ 42 | public function setManufacturer(string $manufacturer): Car 43 | { 44 | $this->manufacturer = $manufacturer; 45 | return $this; 46 | } 47 | 48 | /** 49 | * @return string 50 | */ 51 | public function getManufacturer(): string 52 | { 53 | return $this->manufacturer; 54 | } 55 | 56 | public function __toString() 57 | { 58 | return $this->model; 59 | } 60 | } -------------------------------------------------------------------------------- /Behavioral/Chain Of Responsibility/php-example/src/Entity/Person.php: -------------------------------------------------------------------------------- 1 | name = $name; 29 | return $this; 30 | } 31 | 32 | /** 33 | * @return string 34 | */ 35 | public function getName(): string 36 | { 37 | return $this->name; 38 | } 39 | 40 | /** 41 | * @param int $age 42 | * @return Person 43 | */ 44 | public function setAge(int $age): Person 45 | { 46 | $this->age = $age; 47 | return $this; 48 | } 49 | 50 | /** 51 | * @return int 52 | */ 53 | public function getAge(): int 54 | { 55 | return $this->age; 56 | } 57 | 58 | /** 59 | * @param string $gender 60 | * @return Person 61 | */ 62 | public function setGender(string $gender): Person 63 | { 64 | $this->gender = $gender; 65 | return $this; 66 | } 67 | 68 | /** 69 | * @return string 70 | */ 71 | public function getGender(): string 72 | { 73 | return $this->gender; 74 | } 75 | 76 | public function __toString() 77 | { 78 | return $this->name; 79 | } 80 | } -------------------------------------------------------------------------------- /Behavioral/Chain Of Responsibility/php-example/src/Handlers/AbstractHandler.php: -------------------------------------------------------------------------------- 1 | nextHandler = $handler; 18 | 19 | return $handler; 20 | } 21 | 22 | /** 23 | * {@inheritDoc} 24 | */ 25 | public function handle($request): ?string 26 | { 27 | if (isset($this->nextHandler)) { 28 | return $this->nextHandler->handle($request); 29 | } 30 | 31 | return null; 32 | } 33 | } -------------------------------------------------------------------------------- /Behavioral/Chain Of Responsibility/php-example/src/Handlers/CarsHandler.php: -------------------------------------------------------------------------------- 1 | getModel()}> will be handled by me."; 18 | } 19 | 20 | return parent::handle($request); 21 | } 22 | } -------------------------------------------------------------------------------- /Behavioral/Chain Of Responsibility/php-example/src/Handlers/PeopleHandler.php: -------------------------------------------------------------------------------- 1 | getName()}> will be handled by me."; 18 | } 19 | 20 | return parent::handle($request); 21 | } 22 | } -------------------------------------------------------------------------------- /Behavioral/Chain Of Responsibility/php-example/tests/index.php: -------------------------------------------------------------------------------- 1 | setName('Ahmad'); 13 | $person->setAge(26); 14 | $person->setGender('Male'); 15 | 16 | # Create a car object 17 | $car = new Car(); 18 | $car->setModel('2020 BMW 2-Series Gran Coupe'); 19 | $car->setManufacturer('BMW'); 20 | 21 | # Define the Handlers and create the COR 22 | $peopleHandler = new PeopleHandler(); 23 | $carsHandler = new CarsHandler(); 24 | 25 | $peopleHandler->setNext($carsHandler); 26 | 27 | 28 | # Let's see in practice 29 | foreach ([$person, $car, "tests"] as $object) { 30 | echo "Client: Who wants to handle me {$object}? \n"; 31 | $result = $peopleHandler->handle($object); 32 | 33 | if ($result) { 34 | echo ' ' . $result . "\n"; 35 | } else { 36 | echo ' <' . $object . "> was left untouched.\n"; 37 | } 38 | echo "\n\n"; 39 | } -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # Design Patterns 2 | 3 | ### Requirements: 4 | * Basic knowledge of Object Oriented Programming. 5 | * PHP 7.4 6 | 7 | ### [Behavioral pattern](https://en.wikipedia.org/wiki/Behavioral_pattern) 8 | * [Chain of Responsibility pattern](Behavioral/Chain%20Of%20Responsibility). 9 | * [PHP example](Behavioral/Chain%20Of%20Responsibility/php-example) 10 | 11 | 12 | ### Contribute: 13 | If you want to contribute to this project will be awesome, so please follow the following steps to make it easier for review and merge: 14 | * Fork the repo under your account. 15 | * **If adding new patterns** create a new branch as following example: `structure/adapter` then open a PR to the master branch here. 16 | * Don't forget to Update the main ReadMe with a Link to the new pattern and also to the example mentioning the example language. 17 | * **If the changes are updating or fixing issues** so please make the branch name as the following example `fix/adapter-pattern-example` or `fix/adapter-pattern-readme` 18 | * **If it is adding new language example** make it `adapter-pattern/ruby-example`. 19 | --------------------------------------------------------------------------------