Definition: A class should have one and only one reason to change, meaning that a class should have only one job. Ex: A class that calculates area of a shape also manages authentication, connection to db and rendering. WRONG! Problems of GOD class:
Definition: Objects or entities should be open for extension, but closed for modification.
For PHP:
public function sum() { foreach ($this->shapes as $shape) { if(is_a($shape, 'Square')){ $area[] = pow($shape->length, 2); } elseif (is_a($shape, 'Circle')){ $area[] = pi() * pow($shape->radius, 2); } } return array_sum($area); }
=> Create an interface for all different shapes and make the method "area" compulsory
Definition: Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.
Tesla
is a subtype of a Car
, then I should be able to drive
either a Car
or a Tesla
the same way.Definition: A client should never be forced to implement an interface that it doesn't use or clients shouldn't be forced to depend on methods they do not use.
interface WorkerInterface { public function work(); public function sleep(); } class Worker implements WorkerInterface { public function work(){} public function sleep(){} } class Android implements WorkerInterface { public function work(){} public function sleep(){ return null; } } class Captain { public function manage (WorkerInterface $worker) { $worker->work(); $worker->sleep(); } }
=>
interface WorkableInterface { public function work(); } interface SleepableInterface { public function sleep(); } class Worker implements WorkableInterface, SleepableInterface{ public function work(){} public function sleep(){} } class Android implements WorkableInterface { public function work(){} } class Captain { public function manage (¿?¿?¿? $worker) { $worker->work(); $worker->sleep(); } }
=>
interface ManageableInterface { public function beManaged(); } interface WorkableInterface { public function work(); } interface SleepableInterface { public function sleep(); } class Worker implements WorkableInterface, SleepableInterface, ManageableInterface{ public function work(){} public function sleep(){} public function beManaged(){ $this->work(); $this->sleep(); } } class Android implements WorkableInterface, ManageableInterface { public function work(){} public function beManaged(){ $this->work(); } } class Captain { public function manage (ManageableInterface $worker) { $worker->beManaged(); } }
Definition:
Module
object should not depend on a Child
object, but rather on ChildInterface
or AbstractChild
.
Abstractions should not depend upon details. Details should depend upon abstractions.
And a Child
object should receive calls not from a Module
class but from a ModuleInterface
Put simply, this means our dependencies should be interfaces/contracts or abstract classes rather than concrete implementations.
class PasswordReminder { private $dbConnection; public function __construct(MySQLConnection $dbConnection) { $this->dbConnection = $dbConnection; } }
PasswordReminder => hig level MySQLConnection => low level =>
interface DBConnectionInterface { public function connect(); } class MySQLConnection implements DBConnectionInterface { public function connect() { return "Database connection"; } } class PasswordReminder { private $dbConnection; public function __construct(DBConnectionInterface $dbConnection) { $this->dbConnection = $dbConnection; } }
https://medium.com/backticks-tildes/the-s-o-l-i-d-principles-in-pictures-b34ce2f1e898