ArtisanTinkerer.github.io

Blog

View on GitHub

Single Responsibility

S in SOLID - single responsibility

“A class should have one, and only one, reason to change”

“A class should have one job”

Examples:

Sales reporter should not have authentication in “extract to controller”

Querying the db and doing a calculation.

Formatting output.

Class would have to change, if we need to change either of these.

This violates single responsibility

How Fixed

Querying the db and doing a calculation. This was moved to a repository.

Formatting output.

1, Leave this to the consumer.

This is not the sales reporters job, so this means it needs to go.

2,

In the Reporting folder, create an interface.

interface SalesOutputInterface
{

  public function output($sales);
  

}

//and output classes which implement this

class HtmlOutput implements SalesOutputInterface {

  public function output()
  {
    return "<h1>$sales</h1>";
  }

}

Open Closed

“Entities should be open for extension but closed for modification.”

“open for extension” - easy to change behaviour. “closed for modifications” - change without modifying source code - extension

Modify behaviour without ever touching the original source. = avoid code rot


class Square {

  public $width;
  public $height;
  
  function __construct($height, $width)
  {
    $this->height = $height;
    $this->width = $width;
    
  }
}

“We want to calculate the area”

class AreaCalculator{

  public function calculate($squares)
  
  
  {
  
      $area = 0;
      foreach($squares as $square)
      {
      
        $area += $square->width * $square->height;
      
      }
      
      retuen $area;
  
  }

}

“We also need circles”

class Circles {

  public $radius;
  
  
  function __construct($radius)
  {
  
    $this->radius = $radius;  
    
  }
}

Now we need the area! Edit the original code = broken open/close principle.

I think - interface and then implement for each shape?

** Separate extensible behaviour behind an interface and flip the dependencies.**

Interface is a contract.

“Code to an interface”.

Polymorphism - sharing a common interface,

Liskov Substitution

“Code to an interface”.

“Derived classes must be substitutable for their base classes”

Interface Segregation

“A client should not be forced to implement an interface that it doesn’t use.”

Star Trek example.

interface WorkerInterface{
  public function work();
  public function sleep();
}

class HumanWorker implements WorkerInterface{

  public function work(){
  
  }
  
  public function sleep(){
  
  }

}


class Captain {
  public function manage(Worker $worker){
    $worker->work();
    $worker->sleepk();
  }
  
}

Now we want to employ androids - they don’t sleep.

Should not be forced to implemet sleep method. - Violates interface segregation

Solution

Create two interfaces: WorkableInterface and SleepableInterface HumanWorker implements WorkableInterface, SleepableInterface

AndroidWorker implements WorkableInterface

** Not sure i get the final stage of this **

Dependency Inversion

“Depend on abstractions, not on concretions”

High level Code

Not concerned with details

Low level Code

More concerned with details and specifics.

One class should not be forced to depend upon an implementation. Should depend on abstract, contract or interface

Plugs and sockets, not wiring to wire.

House provides outlet (intercace). Anything which requires power must get it through this interface.

Example: Passing MYSQL connection to PasswordReminder. - bad, why does PasswordReminder care about the db?

High level modules (PasswordReminder) should not depend on low level modules (MySQLConnection).

High level modules should depend on abstractions.

** Instead code to an interface. **

interface ConnectionInterface {
  public function connect();
}


Now PasswordReminder can depend on a ConnectionInterface.

public function __construct(ConnectionInterface $dbConnection)

Watch Repositories

https://scotch.io/bar-talk/s-o-l-i-d-the-first-five-principles-of-object-oriented-design