practical object-oriented design principles · the dependency inversion principle states that...
TRANSCRIPT
![Page 1: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/1.jpg)
Practical Object-Oriented Design Principles
Brandon Savage
![Page 2: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/2.jpg)
What is object-oriented design?
![Page 3: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/3.jpg)
Focus on objects
![Page 4: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/4.jpg)
Focus on extensibility
![Page 5: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/5.jpg)
Focus on reusability
![Page 6: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/6.jpg)
Focus on ease of maintenance
![Page 7: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/7.jpg)
Basic Principles
![Page 8: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/8.jpg)
SOLID
![Page 9: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/9.jpg)
• Single Responsibility Principle
• Open/Closed Principle
• Liskov Substitution Principle
• Interface Segregation Principle
• Dependency Inversion Principle
![Page 10: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/10.jpg)
SOLID is a great acronym. But let’s mix up
the order.
![Page 11: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/11.jpg)
Dependency Inversion
![Page 12: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/12.jpg)
(This is not the dependency injection
principle)
![Page 13: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/13.jpg)
The dependency inversion principle states that high-level modules should not depend on
low-level modules. Both should depend on abstractions.
Also, abstractions should not depend on details; details should depend on abstractions.
![Page 14: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/14.jpg)
What is Dependency Injection?
![Page 15: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/15.jpg)
Hard-Coded Dependencies
<?php
class Controller { public function __construct() { $this->cache = new ApcCache(); } public function manageData() { return $this->cache->get('someKey'); } }
![Page 16: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/16.jpg)
Hard-Coded Dependencies
<?php
class Controller { public function __construct() { $this->cache = new ApcCache(); } public function manageData() { return $this->cache->get('someKey'); } }
![Page 17: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/17.jpg)
Easy to use.
Hard to test.
![Page 18: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/18.jpg)
Easy to use
<?php
$controller = new Controller();
![Page 19: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/19.jpg)
Easy to use.
Impossible to substitute.
![Page 20: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/20.jpg)
No substitution.<?php
class Controller { public function __construct() { $this->cache = new ApcCache(); } public function manageData() { return $this->cache->get('someKey'); } }
![Page 21: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/21.jpg)
Service location
![Page 22: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/22.jpg)
Service Location<?php
class Controller { public function __construct($cache = 'APCCache') { $this->cache = CacheLocator::locate($cache); } public function manageData() { return $this->cache->get('someKey'); } }
![Page 23: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/23.jpg)
Service Location<?php
class Controller { public function __construct($cache = 'APCCache') { $this->cache = CacheLocator::locate($cache); } public function manageData() { return $this->cache->get('someKey'); } }
![Page 24: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/24.jpg)
Service Location<?php
class Controller { public function __construct($cache = 'APCCache') { $this->cache = CacheLocator::locate($cache); } public function manageData() { return $this->cache->get('someKey'); } }
![Page 25: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/25.jpg)
Now we’re tied to the locator.
![Page 26: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/26.jpg)
Dependency Injection
![Page 27: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/27.jpg)
Dependency Injection<?php
class Controller { public function __construct(APCCache $cache) { $this->cache = $cache; } public function manageData() { return $this->cache->get('someKey'); } }
![Page 28: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/28.jpg)
Dependency Injection<?php
class Controller { public function __construct(APCCache $cache) { $this->cache = $cache; } public function manageData() { return $this->cache->get('someKey'); } }
![Page 29: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/29.jpg)
Harder to use.
Easier to test.
![Page 30: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/30.jpg)
Harder to use
<?php
$controller = new Controller(new APCCache);
![Page 31: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/31.jpg)
Harder to use.
Easier to substitute.
![Page 32: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/32.jpg)
That’s dependency injection.
No more, no less.
![Page 33: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/33.jpg)
Dependency Inversion
![Page 34: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/34.jpg)
Dependency Injection refers to the strategy for providing objects to other objects.
It describes a methodology for how to manage dependent objects.
![Page 35: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/35.jpg)
The dependency inversion principle states that high-level modules should not depend on
low-level modules. Both should depend on abstractions.
Also, abstractions should not depend on details; details should depend on abstractions.
![Page 36: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/36.jpg)
A Caching Interface<?php
interface Cache {
public function get($key);
public function set($key, $value);
public function delete($key);
// Purge the whole cache public function purge();
}
![Page 37: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/37.jpg)
Dependency Injection<?php
class Controller { public function __construct(APCCache $cache) { $this->cache = $cache; } public function manageData() { return $this->cache->get('someKey'); } }
![Page 38: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/38.jpg)
Dependency Inversion<?php
class Controller { public function __construct(Cache $cache) { $this->cache = $cache; } public function manageData() { return $this->cache->get('someKey'); } }
![Page 39: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/39.jpg)
We rely on the abstraction of the Cache
interface.
![Page 40: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/40.jpg)
APCCache can’t easily be substituted (LSP Violation)
![Page 41: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/41.jpg)
By relying on the interface, we make
testing easier.
![Page 42: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/42.jpg)
A Development Cache<?php
class VoidCache implements Cache {
public function get($key) { return null; }
public function set($key, $value) { return true; }
public function delete($key) { return true; }
// Purge the whole cache public function purge() { return true; } }
![Page 43: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/43.jpg)
Creating Objects
<?php
// Production $controller = new Controller(new APCCache);
// Development $controller = new Controller(new VoidCache);
![Page 44: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/44.jpg)
How can we do proper dependency injection in
PHP?
![Page 45: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/45.jpg)
How can we switch dependencies between
production and development?
![Page 46: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/46.jpg)
DI Containers
![Page 47: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/47.jpg)
A DI container is simply a programatic way of
injecting dependencies.
![Page 48: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/48.jpg)
A DI Container<?php
class Container { /** * @var array */ protected $registry = [];
/** * @param $className * @param callable $builder */ public function register($className, callable $builder) { $this->registry[$className] = $builder; }
/** * @param $className * @return mixed */ public function build($className) { if (!isset($this->registry[$className])) { throw new \InvalidArgumentException(
$className . ' is not registered'); }
return $this->registry[$className](); } }
![Page 49: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/49.jpg)
Caching Strategies<?php
// production.php
return ['cacheStrategy' => 'APCCache',
];
// dev.php
return ['cacheStrategy' => 'VoidCache',
];
![Page 50: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/50.jpg)
Building Our Objects
<?php
$di->register('Controller', function() use ($config, $di) { return new Controller( $di->build($config['cacheStrategy']) ); });
![Page 51: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/51.jpg)
PHP DI Containers
• Pimple
• PHP-DI
• Aura.Di
• All Major Frameworks
![Page 52: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/52.jpg)
DI containers belong in the bootstrapping layer.
![Page 53: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/53.jpg)
DI Container Antipattern<?php
class User_Controller { public function __construct(Di $di) { $this->di = $di; }
public function getUserContacts() { $cache = $di->get('cache'); if ($contacts = $cache->get('user_contacts')) { return $contacts; } } }
![Page 54: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/54.jpg)
Service location is not dependency inversion!
![Page 55: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/55.jpg)
Not Dependency Inversion<?php
function delete($id) { $profile = Profile::prospect()->find($id);
if (!$profile) { return Rest::notFound(); } if ($profile->delete()) { return Rest::okay([]); } return Rest::conflict(); }
![Page 56: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/56.jpg)
If we’re using abstractions, we can easily substitute one object for another.
![Page 57: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/57.jpg)
Liskov Substitution Principle
![Page 58: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/58.jpg)
The Liskov substitution principle states that objects in a program should be replaceable
with instances of their subtypes without altering the correctness of the program.
E.g. if A is a type of D, then A can replace instances of D.
![Page 59: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/59.jpg)
We’re programming to an interface, not an implementation.
![Page 60: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/60.jpg)
Design by contract
![Page 61: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/61.jpg)
Design by contract is a philosophy which states that designers should define formal,
precise and verifiable interface specifications for software components.
![Page 62: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/62.jpg)
A Contract<?php
interface Cache {
public function get($key);
public function set($key, $value);
public function delete($key);
// Purge the whole cache public function purge();
}
![Page 63: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/63.jpg)
All instances of Cache can be substituted for
one another!
![Page 64: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/64.jpg)
Substitution
<?php
class Controller { public function __construct(Cache $cache) { $this->cache = $cache; } }
$controller = new Controller(new File());
$controller2 = new Controller(new APC());
![Page 65: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/65.jpg)
What happens if our subclass changes the
interface?
![Page 66: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/66.jpg)
Caching Interface<?php
interface Cache {
public function get($key);
public function set($key, $value);
public function delete($key);
// Purge the whole cache public function purge();
}
![Page 67: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/67.jpg)
Extending the Interface
<?php
class MemcacheCache implements Cache { // all the other methods public function reconnect() { $this->memcache->connect($this->host, $this->port); } }
![Page 68: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/68.jpg)
LSP Breaks<?php
class User_Controller { public function __construct(Cache $cache) { $this->cache = $cache; }
public function getUserContacts() { $cache->reconnect(); if ($contacts = $cache->get('user_contacts')) { return $contacts; } } }
![Page 69: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/69.jpg)
Open/Closed Principle
![Page 70: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/70.jpg)
Software entities (classes, modules, functions, etc.) should be open for extension, but closed
for modification.
![Page 71: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/71.jpg)
Two kinds of open/closed principle
![Page 72: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/72.jpg)
Meyer’s Open/Closed Principle
![Page 73: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/73.jpg)
Classes are open for extension through inheritance, but closed
to internal modification.
![Page 74: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/74.jpg)
- Bertrand Meyer
A class is closed, since it may be compiled, stored in a library, baselined, and used by client classes. But it is also open, since any new class
may use it as parent, adding new features. When a descendant class is defined, there is no need to change the original or to disturb its
clients.
![Page 75: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/75.jpg)
Polymorphic Open/Closed Principle
![Page 76: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/76.jpg)
Once defined, the interface cannot be changed (but
the internals can)
![Page 77: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/77.jpg)
“Interface” refers to the publicly visible methods.
![Page 78: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/78.jpg)
While the original interface should be honored, implementation is up
to the developer.
![Page 79: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/79.jpg)
The interface should not be modified.
![Page 80: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/80.jpg)
When modifying the interface, you change an
object’s type.
![Page 81: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/81.jpg)
Class vs. Type
![Page 82: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/82.jpg)
Class is the name of the class that defines a particular object.
![Page 83: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/83.jpg)
Type is the behavior of the object as expressed through public methods.
![Page 84: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/84.jpg)
Extending the interface changes the object’s
type.
![Page 85: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/85.jpg)
New Object Type<?php
class User_Controller { public function __construct(MemcacheCache $cache) { $this->cache = $cache; }
public function getUserContacts() { $cache->reconnect(); if ($contacts = $cache->get('user_contacts')) { return $contacts; } } }
![Page 86: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/86.jpg)
The return type is part of the interface, too!
![Page 87: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/87.jpg)
Single Return Type
![Page 88: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/88.jpg)
(All Others Use Exceptions)
![Page 89: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/89.jpg)
PHP 7 Return Type Declaration
![Page 90: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/90.jpg)
Return Type Declaration<?php
interface Cache {
public function get($key): string;
public function set($key, $value): bool;
public function delete($key): bool;
// Purge the whole cache public function purge(): bool;
}
![Page 91: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/91.jpg)
So if extending the interface isn’t allowed, what kind of interfaces do we want?
![Page 92: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/92.jpg)
Interface Segregation
![Page 93: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/93.jpg)
The interface segregation principle states that no object should be forced to depend upon or
implement methods it does not use.
Smaller interfaces are better.
![Page 94: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/94.jpg)
Small Interfaces
<?php
interface Countable { public function count(); }
![Page 95: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/95.jpg)
Small Interfaces<?php
interface Iterator extends Traversable { public function current(); public function key(); public function next(); public function rewind(); public function valid(); }
![Page 96: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/96.jpg)
Small Interfaces<?php
class ArrayClass implements Iterator, Countable { public $collection = []; public function count() { return count($this->collection); }
public function current() { return current($this->collection); }
public function key() { return key($this->collection); }
public function next() { return next($this->collection); }
public function rewind() { reset($this->collection); }
public function valid() { return (bool) $this->current(); } }
![Page 97: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/97.jpg)
Objects can have more than one type!
![Page 98: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/98.jpg)
Object Types<?php
class ArrayClass implements Iterator, Countable { public $collection = []; public function count() { return count($this->collection); }
public function current() { return current($this->collection); }
public function key() { return key($this->collection); }
public function next() { return next($this->collection); }
public function rewind() { reset($this->collection); }
public function valid() { return (bool) $this->current(); } }
![Page 99: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/99.jpg)
Small interfaces help us keep objects discrete and single-focused.
![Page 100: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/100.jpg)
Single Responsibility Principle
![Page 101: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/101.jpg)
The single responsibility principle states that every class should have a single responsibility
and that responsibility should be entirely encapsulated by that class. All its services
should be narrowly aligned with that responsibility.
![Page 102: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/102.jpg)
One class, one job.
![Page 103: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/103.jpg)
One class, one job.
![Page 104: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/104.jpg)
One class, one responsibility.
![Page 105: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/105.jpg)
One domain.
![Page 106: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/106.jpg)
A class can have many jobs, but a single domain.
![Page 107: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/107.jpg)
PDO’s Jobs
• Begin and end transactions
• Establish and maintain connection to the database.
• Send simple queries to the database.
• Prepare complex queries, returning a statement object.
![Page 108: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/108.jpg)
PDOStatement’s Jobs
• Represent a single PDO statement.
• Execute the PDO statement.
• Return the results.
![Page 109: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/109.jpg)
PDO’s domain is over the connection and queries
to the connection.
![Page 110: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/110.jpg)
PDOStatement’s domain is over a specific prepared statement and its results.
![Page 111: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/111.jpg)
…entirely encapsulated…
![Page 112: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/112.jpg)
“A single reason to change.” ~ Robert Martin
![Page 113: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/113.jpg)
- Robert Martin
Gather together the things that change for the same reasons. Separate those things that
change for different reasons.
![Page 114: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/114.jpg)
Law of Demeter
![Page 115: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/115.jpg)
Who can my objects talk to?
![Page 116: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/116.jpg)
What should my objects know?
![Page 117: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/117.jpg)
The Law of Demeter (LoD) states that objects should have limited knowledge. Specifically,
they should have limited knowledge about other units, only talk to its friends, not strangers, and
only talk to its immediate friends.
![Page 118: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/118.jpg)
Limited knowledge
![Page 119: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/119.jpg)
Unit Knowledge
<?php
class MyController { public function __construct( Memcache $memcacheConnection ) { $this->cache = new Memcache_Cache($memcacheConnection); } }
![Page 120: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/120.jpg)
Only Close Friends
<?php
class MyController { public function someMethod() { $this->object ->someParameter ->someOtherParameter ->someMethod(); } }
![Page 121: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/121.jpg)
Talk only to close friends.
![Page 122: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/122.jpg)
Formal Law of Demeter
• The Object itself.
• The method’s parameters.
• Any objects created/instantiated by the method.
• The Object’s component objects.
From Wikipedia
![Page 123: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/123.jpg)
Advantages
![Page 124: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/124.jpg)
Lower coupling.
![Page 125: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/125.jpg)
Maintainability.
![Page 126: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/126.jpg)
Adaptability.
![Page 127: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/127.jpg)
Disadvantages
![Page 128: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/128.jpg)
Lots of wrapper calls.
![Page 129: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/129.jpg)
May not be entirely practical.
![Page 130: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/130.jpg)
Antipatterns In Object-Oriented Design
![Page 131: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/131.jpg)
Singleton
![Page 132: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/132.jpg)
The singleton pattern is a software design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across
the system.
![Page 133: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/133.jpg)
The Singleton<?php
class MySingleton {
private static $instance;
private function __construct() {}
private function __clone() {}
public static function getInstance() { if (!(self::$instance instanceof MySingleton)) { self::$instance = new MySingleton(); } return self::$instance; }
}
![Page 134: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/134.jpg)
Singletons themselves aren’t bad.
Using them inappropriately is bad.
![Page 135: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/135.jpg)
Most problems can be solved without a
singleton.
![Page 136: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/136.jpg)
Tight Coupling
![Page 137: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/137.jpg)
![Page 138: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/138.jpg)
Tight Coupling slowly strangles a code base.
![Page 139: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/139.jpg)
Law of Demeter
![Page 140: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/140.jpg)
Untestable Code
![Page 141: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/141.jpg)
Tightly coupled code can’t be easily tested.
![Page 142: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/142.jpg)
Untestable
<?php
class Database { public function __construct() { $this->cache = new ApcCache(); } }
![Page 143: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/143.jpg)
Testable
<?php
class Database { public function __construct(Cache $cache) { $this->cache = $cache; } }
![Page 144: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/144.jpg)
Proper testing often requires stubs, substitutes,
mocks and doubles.
![Page 145: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/145.jpg)
Premature Optimization
![Page 146: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/146.jpg)
It can be tempting to optimize your code as
you write it.
![Page 147: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/147.jpg)
Avoid the temptation.
![Page 148: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/148.jpg)
When optimizing, you need real-world
conditions.
![Page 149: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/149.jpg)
When optimizing, you need to measure.
![Page 150: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/150.jpg)
Avoid micro-optimizations.
![Page 151: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/151.jpg)
Avoid being clever.
![Page 152: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/152.jpg)
Don’t Repeat Yourself
![Page 153: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/153.jpg)
Duplication is a hallmark of tight coupling
![Page 154: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/154.jpg)
Duplicated code means duplicated tests.
![Page 155: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/155.jpg)
N duplication means N opportunities for
mistakes.
![Page 156: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/156.jpg)
Indescriptive Naming
![Page 157: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/157.jpg)
Code is written for humans.
Communicate purpose.
![Page 158: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/158.jpg)
Pick names that matter.
![Page 159: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/159.jpg)
Bad names
$i
$abc$def
$foo
$thing$that
![Page 160: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/160.jpg)
Good names
$forIterator
$cache$masterDatabase
$deleteUserCommand
$jobQueue$createUserEvent
![Page 161: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/161.jpg)
Use actual words in docblocks!
![Page 162: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/162.jpg)
Bad Dockblock
<?php
/** * @param $xdd */ public function processXdd($xdd) { // do something }
![Page 163: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/163.jpg)
Good Docblock
<?php
/** * Processes a single XDD for removal and archive. * * @param $xdd */ public function processXdd($xdd) { // do something }
![Page 164: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/164.jpg)
Exceptions
![Page 165: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/165.jpg)
Exceptions are the default error handling for object-oriented programming.
![Page 166: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/166.jpg)
Exceptions are objects.
![Page 167: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/167.jpg)
Exceptions are objects<?php
$object = new Exception;
var_dump($object);
// object(Exception)[1] protected 'message' => string '' (length=0) private 'string' => string '' (length=0) protected 'code' => int 0 protected 'file' => string '/Users/brandon/Sites/test.php' (length=29) protected 'line' => int 3 private 'trace' => array (size=0) empty private 'previous' => null
![Page 168: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/168.jpg)
Exceptions are exceptional!
(not for control flow)
![Page 169: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/169.jpg)
You shouldn’t expect an exception.
(but you should handle it)
![Page 170: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/170.jpg)
The Exception API
![Page 171: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/171.jpg)
Exceptions are Extensible
<?php
class MyException extends Exception {}
![Page 172: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/172.jpg)
Exceptions are extended to make it easier to differentiate between different kinds of errors.
We can catch specific types of exceptions through type hinting.
![Page 173: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/173.jpg)
Throwing An Exception
<?php
throw new MyException('Something went wrong');
![Page 174: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/174.jpg)
Exceptions are thrown in PHP.
![Page 175: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/175.jpg)
Exceptions are special - they’re the only objects
you can throw.
![Page 176: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/176.jpg)
Handling an exception means you caught it.
![Page 177: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/177.jpg)
Catching Exceptions
<?php
function caughtExceptions() { try { // do something dangerous } catch (Exception1 $e) { // Do stuff } catch (Exception2 $e) { // do other stuff. } }
![Page 178: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/178.jpg)
Catching Exceptions
<?php
function caughtExceptions() { try { // do something dangerous } catch (Exception1 $e) { // Do stuff } catch (Exception2 $e) { // do other stuff. } }
![Page 179: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/179.jpg)
We type-hint the exception.
<?php
function caughtExceptions() { try { // do something dangerous } catch (Exception1 $e) { // Do stuff } catch (Exception2 $e) { // do other stuff. } }
![Page 180: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/180.jpg)
We can catch multiple exception types.
<?php
function caughtExceptions() { try { // do something dangerous } catch (Exception1 $e) { // Do stuff } catch (Exception2 $e) { // do other stuff. } }
![Page 181: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/181.jpg)
Multiple exception catching rules
• PHP will execute the first block that matches the exception type.
• You can rethrow an exception, but it will only be caught if it’s inside a try-catch block.
• Type-hint on specific exceptions first, before type-hinting on broader exception types (like \Exception)
![Page 182: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/182.jpg)
Exception Catching Rules
<?php
class MyException extends Exception {}
class MyExceptionTwo extends MyException {}
![Page 183: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/183.jpg)
Exception Catching Rules
<?php
try { throw new MyExceptionTwo('test'); } catch (MyException $e) { echo 'MyException'; } catch (MyExceptionTwo $e) { echo 'MyExceptionTwo'; } catch (Exception $e) { echo 'Exception'; }
![Page 184: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/184.jpg)
Exception Catching Rules
<?php
try { throw new MyExceptionTwo('test'); } catch (MyException $e) { echo 'MyException'; } catch (MyExceptionTwo $e) { echo 'MyExceptionTwo'; } catch (Exception $e) { echo 'Exception'; }
![Page 185: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/185.jpg)
Exception Catching Rules
<?php
try { throw new MyExceptionTwo('test'); } catch (MyExceptionTwo $e) { echo 'MyExceptionTwo'; } catch (MyException $e) { echo 'MyException'; } catch (Exception $e) { echo 'Exception'; }
![Page 186: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/186.jpg)
Exception Catching Rules
<?php
try { throw new MyExceptionTwo('test'); } catch (MyExceptionTwo $e) { echo 'MyExceptionTwo'; } catch (MyException $e) { echo 'MyException'; } catch (Exception $e) { echo 'Exception'; }
![Page 187: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/187.jpg)
Finally
![Page 188: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/188.jpg)
Finally<?php
try { throw new MyExceptionTwo('test'); } catch (MyExceptionTwo $e) { echo 'MyExceptionTwo'; } catch (MyException $e) { echo 'MyException'; } catch (Exception $e) { echo 'Exception'; } finally { echo "This will always be executed."; }
![Page 189: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/189.jpg)
Finally is always executed.
Even if the exception is unhandled.
![Page 190: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/190.jpg)
In PHP 7, errors become exceptions.
![Page 191: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/191.jpg)
Errors as ExceptionsThrowable
Error Exception
AssertionError ParseError TypeError
![Page 192: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/192.jpg)
All exceptions now implement the Throwable
interface.
![Page 193: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/193.jpg)
Throwable Interface
<?php
interface Throwable { public function getMessage(); public function getCode(); public function getFile(); public function getLine(); public function getTrace(); public function getTraceAsString(); public function getPrevious(); public function __toString();
}
![Page 194: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/194.jpg)
All errors are catchable.
![Page 195: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/195.jpg)
(You should not ignore fatal errors)
![Page 196: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/196.jpg)
Hint on “Throwable” to catch all errors.
![Page 197: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/197.jpg)
You can’t implement Throwable yourself.
![Page 198: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/198.jpg)
No Implementing Throwable
<?php
class ExceptionA implements Throwable { }
new ExceptionA;
//
Fatal error: Class ExceptionA cannot implement interface Throwable, extend Exception or Error instead
![Page 199: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/199.jpg)
PHP 7.1: Multi-Catch Exception Handling
![Page 200: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/200.jpg)
Exception Catching Rules
<?php
try { throw new MyExceptionTwo('test'); } catch (MyExceptionTwo | MyException $e) { echo 'MyExceptionTwo'; } catch (Exception $e) { echo 'Exception'; }
![Page 201: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/201.jpg)
Rules for Exception Handling
![Page 202: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/202.jpg)
#1. Always handle exceptions at the lowest logical layer, rather than letting them bubble up.
E.g. if a database layer throws an exception, handle it in the layer that called the database
layer.
![Page 203: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/203.jpg)
#2. Each layer should be capable of throwing its own exceptions, and should not rely on the
exceptions of another layer.
E.g. if your model receives a database exception it cannot handle, it should throw its own exception. It’s okay to wrap the database
exception.
![Page 204: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/204.jpg)
#3. If something can go wrong, it should have an expected exception.
![Page 205: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/205.jpg)
#4. Do not allow for a return value of null from a method on an error condition. Throw an
exception instead.
![Page 206: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/206.jpg)
Bad
<?php
function checkMath($a, $b, $answer) { if($a + $b == $answer) { return $answer; } else { return false; } }
![Page 207: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/207.jpg)
Good
<?php
function checkMath($a, $b, $answer) { if($a + $b == $answer) { return $answer; } else { throw new \Exception('The math didn\'t check out!'); } }
![Page 208: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/208.jpg)
#5. Expect exceptions.
![Page 209: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/209.jpg)
Action Domain Responder
![Page 210: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/210.jpg)
How we do it now: Model-View-Controller
![Page 211: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/211.jpg)
Classic MVCModel
View Controller
User
![Page 212: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/212.jpg)
MVC has a number of problems.
![Page 213: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/213.jpg)
We don’t actually follow this.Model
View Controller
User
![Page 214: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/214.jpg)
We follow this.Model
View Controller
User
![Page 215: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/215.jpg)
Actually, we kinda do this.Model
Template Controller
User
![Page 216: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/216.jpg)
Our controller ends up doing all the work.
![Page 217: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/217.jpg)
Model Controller View
Request
![Page 218: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/218.jpg)
Model Controller View
Request
![Page 219: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/219.jpg)
Model Controller View
Request
Business Logic
![Page 220: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/220.jpg)
Model Controller View
RequestAlgorithms
Database Logic
![Page 221: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/221.jpg)
Model Controller View
RequestAlgorithms
Database Logic
Template System
![Page 222: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/222.jpg)
Model Controller View
RequestAlgorithms
Database Logic
Template System
![Page 223: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/223.jpg)
Model Controller View
RequestAlgorithms
Database Logic
Template System
Authentication
![Page 224: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/224.jpg)
Model Controller View
RequestAlgorithms
Database Logic
Template SystemAuthentication
![Page 225: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/225.jpg)
That’s a lot of responsibilities.
![Page 226: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/226.jpg)
Introducing a better way
Action-Domain-Responder
![Page 227: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/227.jpg)
Action-Domain-Responder
Action
ResponderDomain
![Page 228: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/228.jpg)
ADR solves many problems associated with
MVC.
![Page 229: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/229.jpg)
Action vs. Controller• Controllers contain several related methods.
Actions are specific to a particular request.
• Controllers interact with both the model and the presentation layer. Actions interact only with the model.
• Actions are responsible for shuffling request data into the domain, and response data out.
![Page 230: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/230.jpg)
Model vs. Domain
• Models are (classically) expected to interact directly with the view. Domains do not interact with the responder.
• The domain does not modify the view directly.
![Page 231: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/231.jpg)
View vs. Responder• “The template is not the view.”
• Responders have a 1:1 relationship to specific actions.
• Responders are responsible for determining how to respond to the request.
• Responders may incorporate a template system.
• The action does not know anything about the presentation logic. This is entirely the responder’s domain.
![Page 232: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/232.jpg)
Action Domain Responder
![Page 233: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/233.jpg)
Action Domain Responder
Request
![Page 234: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/234.jpg)
Action Domain Responder
Request
![Page 235: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/235.jpg)
Action Domain Responder
Request
Business Logic
![Page 236: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/236.jpg)
Action Domain Responder
Request Business Logic
![Page 237: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/237.jpg)
Action Domain Responder
Request Business Logic
Template System
![Page 238: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/238.jpg)
Action Domain Responder
Request Business Logic Template System
![Page 239: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/239.jpg)
Action Domain Responder
Request Business Logic Template System
Authentication
![Page 240: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/240.jpg)
Action Domain Responder
Request Business Logic Template SystemAuthentication ACLs
![Page 241: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/241.jpg)
PSR-7 And HTTP Messages
![Page 242: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/242.jpg)
The problem we’re trying to solve
![Page 243: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/243.jpg)
We want a common way of accepting requests and dispatching responses via HTTP.
PHP was developed primarily for web development, but in many ways sucks at this.
![Page 244: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/244.jpg)
PSR-7 provides a common set of interfaces for HTTP messages (both request and response).
![Page 245: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/245.jpg)
PSR-7 RFCs
• HTTP Messages as described in RFC 7230 and RFC 7231
• URIs as described in RFC 3986
![Page 246: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/246.jpg)
PHP uses HTTP Request messages in two ways
![Page 247: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/247.jpg)
1. Sending an HTTP request
Via cURL, stream layer, or some other means.
![Page 248: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/248.jpg)
#2 Process an incoming HTTP request.
A user makes a request to a web page that is powered and processed by PHP.
![Page 249: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/249.jpg)
Sending a request
![Page 250: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/250.jpg)
PHP does not have built-in support for HTTP
messages.
![Page 251: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/251.jpg)
You must use an add-on for HTTP requests
![Page 252: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/252.jpg)
Mechanisms for requests
• PHP Streams
• The cURL extension
• ext/http
![Page 253: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/253.jpg)
Streams are most common (and built into
PHP)
![Page 254: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/254.jpg)
cURL is available, powerful, but not built-in.
![Page 255: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/255.jpg)
Same with ext/http. (Plus, no examples)
![Page 256: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/256.jpg)
Most modern libraries making HTTP requests use abstraction so they can use any available HTTP
sending mechanism.
![Page 257: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/257.jpg)
Receiving a request
![Page 258: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/258.jpg)
PHP’s SAPI processes query strings and bodies into $_GET and $_POST.
![Page 259: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/259.jpg)
It also takes care of processing cookies, files
and server variables.
![Page 260: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/260.jpg)
A history of PHP development
![Page 261: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/261.jpg)
First, PHP was a templating language.
![Page 262: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/262.jpg)
Superglobals were used everywhere, because that
was all we had.
![Page 263: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/263.jpg)
PHP 4 came along and gave us objects.
![Page 264: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/264.jpg)
PHP 5 came along and gave us better objects.
![Page 265: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/265.jpg)
Objects begat object-oriented frameworks.
![Page 266: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/266.jpg)
Frameworks began defining their own HTTP
components.
![Page 267: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/267.jpg)
PSR-0 standardized autoloading (+ PSR-4)
![Page 268: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/268.jpg)
Composer made library building and distribution
easy.
![Page 269: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/269.jpg)
Libraries for HTTP began to proliferate.
![Page 270: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/270.jpg)
The PHP-FIG saw a need and created PSR-7.
![Page 271: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/271.jpg)
Why PSR-7?
![Page 272: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/272.jpg)
Multiple HTTP implementations is
confusing and wasteful.
![Page 273: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/273.jpg)
Different HTTP specifications makes
interoperability impossible.
![Page 274: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/274.jpg)
Direct use of superglobals is considered harmful.
![Page 275: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/275.jpg)
So the PHP-FIG set out to abstract both client- and server-side
request and response interfaces.
![Page 276: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/276.jpg)
Interoperability
![Page 277: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/277.jpg)
So what did FIG actually do?
![Page 278: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/278.jpg)
Interfaces
![Page 279: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/279.jpg)
PSR-7 Interfaces• Psr\Http\Message\MessageInterface;
• Psr\Http\Message\RequestInterface;
• Psr\Http\Message\ServerRequestInterface;
• Psr\Http\Message\ResponseInterface;
• Psr\Http\Message\StreamInterface;
• Psr\Http\Message\UriInterface;
• Psr\Http\Message\UploadedFileInterface;
![Page 280: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/280.jpg)
The MessageInterface
![Page 281: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/281.jpg)
RequestInterface and ResponseInterface extend
from MessageInterface
![Page 282: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/282.jpg)
URI’s as objects
![Page 283: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/283.jpg)
Immutability
![Page 284: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/284.jpg)
Immutability is the property of being unchangeable. Whenever an immutable
request/response object is “modified”, the return value is a brand new object with the
requested modification. The original remains the same.
![Page 285: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/285.jpg)
Streams
![Page 286: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/286.jpg)
Streams can be hard to work with (StreamInterface
seeks to solve for this)
![Page 287: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/287.jpg)
Streams are mutable!
![Page 288: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/288.jpg)
Stream immutability is impossible to enforce.
![Page 289: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/289.jpg)
Why is there a ServerRequestInterface?
![Page 290: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/290.jpg)
Server-side requests have special needs.
![Page 291: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/291.jpg)
Access to $_GET, $_POST, $_SERVER,
$_COOKIE and $_FILES.
![Page 292: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/292.jpg)
Access to the URI for routing.
![Page 293: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/293.jpg)
Notice: the return value of ServerRequestInterface::
getParsedBody() is indeterminate.
![Page 294: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/294.jpg)
Files are objects.
![Page 295: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/295.jpg)
This fixes several problems with PHP.
![Page 296: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/296.jpg)
array( 'files' => array( 'name' => array( 0 => 'file0.txt', 1 => 'file1.html', ), 'type' => array( 0 => 'text/plain', 1 => 'text/html', ), /* etc. */ ), )
![Page 297: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/297.jpg)
PHP won’t process files not in a POST request
(think PUT).
![Page 298: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/298.jpg)
PSR-15 HTTP Server Request Handlers
![Page 299: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/299.jpg)
PSR-15 defines a standard for creating reusable middleware.
![Page 300: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/300.jpg)
PSR-15 extends the PSR-7 concept by integrating it
directly into the middleware.
![Page 301: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/301.jpg)
Approaches to Middleware Design
![Page 302: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/302.jpg)
The “Double Pass”
<?php
public function handle( ServerRequestInterface $request, ResponseInterface $response, callable $next ) : ResponseInterface;
![Page 303: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/303.jpg)
The “Single Pass” (Lambda)
<?php
public function handle( ServerRequestInterface $request, callable $next ) : ResponseInterface;
![Page 304: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/304.jpg)
Middleware has no access to a response until one is generated
by the request handler.
![Page 305: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/305.jpg)
PSR-15 uses the single pass.
![Page 306: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/306.jpg)
![Page 307: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/307.jpg)
The RequestHandlerInterface
<?php
namespace Psr\Http\Server;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface;
interface RequestHandlerInterface { public function handle(
ServerRequestInterface $request): ResponseInterface; }
![Page 308: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/308.jpg)
The “end of the line.”
![Page 309: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/309.jpg)
RequestHandlerInterface MUST return a response.
![Page 310: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/310.jpg)
The MiddlewareInterface
<?php
namespace Psr\Http\Server;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface;
interface MiddlewareInterface { public function process(
ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface;
}
![Page 311: Practical Object-Oriented Design Principles · The dependency inversion principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions](https://reader033.vdocuments.net/reader033/viewer/2022042302/5ecd8829d525a4298018ed14/html5/thumbnails/311.jpg)
MUST return a response (but may delegate)