Monday, August 27, 2018

SOLID Principles in PHP

  1. Single Responsibility: A Class should be responsible for a single task.
  2. Open-Close Principle: A Class should be open to extension and close to modification.
  3. Liskov Substitution: A derived Class can be substituted at places where base Class is used.
  4. 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.
  5. 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.
  6. 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;
    }
}

No comments:

Post a Comment