├── 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 |
--------------------------------------------------------------------------------