- Single Responsibility: A Class should be responsible for a single task.
- Open-Close Principle: A Class should be open to extension and close to modification.
- Liskov Substitution: A derived Class can be substituted at places where base Class is used.
- Interface Segregation: Don’t make FAT Interfaces. i.e. Classes don’t have to override extra agreements that are not needed for that Class simply because it is there in interface.
- Dependency Inversion: Depend on abstractions, not on concretions. Not only high level Classes but low level Classes also depend on the abstractions in order to decouple the code.
S: Single Responsibility Principle
Each class should have one responsibility and one responsibility only. This means that all the methods and properties should all work towards the same goal.
<?php
class Customer
{
public $name;
public $age;
public function __contsruct($name, $age)
{
$this->name = $name;
$this->age = $age;
}
public function getCustomerDetails()
{
return "Name: ".$this->name." Age: ".$this->age;
}
}
O: Open-closed Principle
It ensures that the code is open for extension but closed for modification
<?php
interface CustomerInterface
{
function getPointsSpent();
}
class RetailCustomer implements CustomerInterface
{
public function getPointsSpent()
{
return $this->type * 0.5;
}
}
class TradeCustomer implements CustomerInterface
{
public function getPointsSpent()
{
return $this->type * 1;
}
}
class PointsCalculator
{
public function getPointsSpent($customerTypes)
{
$amount = 0;
foreach ($customerTypes as $type)
{
$amount += $type->getPointsSpent();
}
return $amount;
}
}
L: Liskov Substitution Principle
This principle basically specifies that child classes should be suitable for their parent classes.
<?php
class Instrument
{
public function play() {..}
public function changeKey() {..}
public function autoTune() {..}
public function plugIn() {..}
}
implemented ways
<?php
class Guitar extends Instrument
{
public function play() {
$this->plugIn();
$this->strum();
parent::play();
}
public function strum() {..}
}
class Trumpet extends Instrument
{
public function play() {
$this->blow();
parent::play();
}
public function blow() {..}
}
I: Interface Segregation Principle
A client should not be forced to use interfaces that it doesn’t need
violation of this principle:example
<?php
interface InstrumentInterface {
public function play();
public function changeKey();
public function autoTune();
public function plugIn();
}
class Guitar implements InstrumentInterface {
public function play() {..}
public function changeKey() {..}
public function autoTune() {..}
public function plugIn() {..}
}
class Trumpet implements InstrumentInterface {
public function play() {..}
public function changeKey() {..}
public function autoTune() { /* Exception */ }
public function plugIn() { /* Exception */ }
}
Splitting the IItem interface into several interfaces.
<?php
interface InstrumentInterface
{
public function play();
public function changeKey();
}
interface GuitarInterface
{
public function autoTune();
public function plugIn();
}
class Guitar implements InstrumentInterface, GuitarInterface
{
public function play() {..}
public function changeKey() {..}
public function autoTune() {..}
public function plugIn() {..}
}
class Trumpet implements InstrumentInterface {
public function play() {..}
public function changeKey() {..}
}
D: Dependency Inversion Principle
This principle states that high level modules should not depend on low level modulesgjh
example of higher level code being dependent on lower level code:
<?php
class CountApples
{
private $apple;
public function __contsruct($apple)
{
$this->apple = $apple;
}
public function howMany()
{
return count($this->apple->howMany());
}
}
<?php
class CountFruit
{
private $fruit;
public function __contsruct($fruit)
{
$this->fruit = $fruit;
}
public function howMany()
{
return count($this->fruit->howMany());
}
}
/** Create our generic fruit interface **/
interface Fruit
{
public function howMany();
}
/** Create our clients **/
class Apples implements Fruit
{
public function howMany()
{
return 14;
}
}
class Bananas implements Fruit
{
public function howMany()
{
return 6;
}
}