Car/Battery

A simple story about better php classes

HORISEN AG

dipl. ing.

Milan Rukavina

Horisen

Use case

  • Car uses battery
  • Car drives, battery provides 12V
  • Car is a class, battery is a class

The Battery

                       
class Battery
{          
    public function supply12v()
    {
        return 12;
    }
}                           
                        
                    

The Bad Car

                       
class BadCar
{   
    protected $battery;
    
    function __construct()
    {
        $this->battery = new Battery();
    }

    
    public function drive()
    {
        $this->battery->supply12v();
    }
}                          
                        
                    

The Better Car

                       
class BetterCar
{   
    protected $battery;
    
    function __construct(Battery $battery)
    {
        $this->battery = $battery;
    }
    
    //...
}                          
                        
                    

Battery Interface

                       

interface BatteryInterface
{          
    public function supply12v();
}                          
                        
                    

The Best Car

                       
class BestCar
{   
    protected $battery;
    
    function __construct(BatteryInterface $battery)
    {
        $this->battery = $battery;
    }    
}                          
                        
                    

A few rules

  • ALL dependencies are injected ONLY via constructor
  • NO setter injections, NO dependencies constructions
  • An objected is ready for usage as soon as constructor is done
  • No 2,3 step contruction/initialization

Advantages

  • Single-responsiblity principle (Solid)
  • Dependency Inversion Principle (soliD)
  • Testability

But Where TF can I call constructor?

  • Dependency Injector Containers (DIC)
  • Laravel IOC
  • Zend Service Manager
  • (Controllers?)

Further reading