SlideShare a Scribd company logo
1 of 39
Download to read offline
S.O.L.I.D
                        Principles



Bastian Feder                        OSIDays 2011, Bangalore
bastian.feder@liip.ch                    21st November 2011
Me, myself & I

 PHP since 2001
 Testing and Quality coach @ Liip Inc.
 Opensource addict
   PHP manual translations
   FluentDOM
   phpDox
News from Uncle Bob

 Essential principles for software development &
 object oriented design (OOD).
 Robert C. Martin summarized those principles,
 but did not invent them.
Which are these principles?

 Single responsibility principle
 Open/Close principle
 Liskov substitution principle
 Interface segregation principle
 Dependency inversion principle
Geolocation Tracker

„As a hiker I want to track where I
walked and how much I climbed.“
„As a developer I want to be able to
store the geo information on different
devices.“
„As a developer I want to store the geo
information in a unified format.“
Single responsibility
 principle (SRP)



„A class should have one, and only
     one, reason to change.“
How to do
it wrong
<?php
namespace lapisTracker;
use lapisTrackerStructs;

class Geolocation extends Tracker
{
   public function trackPosition(Position $position)
   {
     list($langitude, $longitude, $altitude) =
         $this->extractCoordinatesFromPosition($position);
     $altitude = $this->convertFeetToMeter($altitude);
     $this->persistPosition($langitude, $longitude, $altitude, new DateTime());
   }

    public function persistPosition( $langitude, $longitude, $altitude, DateTime $time)
    {
      try{
          $conn = $this->getDatabaseConnection('write');
          $conn->execute($this->generateQuery($langitude, $longitude, $altitude, $time));
       } catch (Exception $e) {
          $this->logError($e->getMessage());
       }
    }
    /** […] */
}
How to do
it right
<?php

namespace lapisTracker;
use lapisTrackerStructsPosition;

class Geolocation extends Tracker
{
   public function __construct(Parser $parser, PersistenceManager $pm)
   { /** […] */ }

    public function trackPosition(Position $position, DateTime $time = null)
    {
      try {
         $coordinates = $this->parser->parsePosition($position);
         $this->pm->persistPosition($coordinates, $time);
      } catch (PersistanceManagerException $e) {
         throw new TrackerException(
            'Unable to persist your position.', TrackerException::PersistError,
            $e
         );
      }
    }
}
Single responsibility
 principle
 Simple to understand, very hard to get right.
 Separation of responsibilities / concerns
 One responsibility per class
Liskov substitution
  principle (LSP)



   „Derived classes must be
  substitutable for their base
           classes.“
Where do
we start
<?php
namespace lapisConverter;

class Distance {
   const FACTOR = 0.3048; // 1 foot in meters

    public function feetToMeters($distance) {
      $this->verifyDistance($distance);
      return $distance * self::FACTOR;
    }

    public function metersToFeet($distance) {
      $this->verifyDistance($distance);
      return $distance / self::FACTOR;
    }

    protected function verifyDistance($distance) {
      if ($distance < 0) {
          throw new OutOfRangeException(
             'Distance may not be lower than zero.',
             DistanceException::OutOfRange
          );
      }
    }
}
How to do
it wrong
<?php

namespace lapisConverterDistance;
use lapisConverter;

class NegativeDistance extends Distance
{
   protected function verifyDistance($distance)
   {
     return TRUE;
   }
}
How to do
it right
<?php
namespace lapisConverterDistance;
use lapisConverter;

class MaxDistance extends Distance {
   public function feetToMeters($distance) {
     $distance = parent::feetToMeters($distance);
     $this->verifyDistance($distance, 15000);
     return $distance;
   }

    protected function verifyDistance($distance, $max = 0) {
      if ($distance < 0) {
          $message = 'Distance may not be lower than the zero.';
      }
      if ($max > 0 && $distance >= $max) {
          $message = 'Distance may not be greater than the maximum of ' . $max . '.';
      }
      If (isset($message) {
          throw new OutOfRangeException($message, DistanceException::OutOfRange);
      }
    }
}
Liskov substitution
  principle
 Design by contract
 User must not distinguish between super- &
 subclasses
 Derived class must be more strict on output, but
 may handle the input less strict.
 Increases maintainability, robustness &
 resusability
Dependency inversion
 principle (DIP)



 „Depend on abstractions, not on
         concretions.“
How to do
it wrong
<?php
namespace lapisTracker;
use lapisTrackerStructsPosition;

class PersistenceManager {
   public function __construct(Tracker $tracker) { /** […] */ }

    public function trackPosition(Position $position) {
      try {
         $this->tracker->trackPosition($position);
         $this->log('Position stored successfully');
      } catch (TrackerException $e) {
         $this->log($e->getMessage());
      }
    }

    protected function log($message) {
       $fh = fopen ('log.txt' , 'a');
       fwrite($fh, $message);
       fclose($fh);
    }
    /** […] */
}
How to do
it right
<?php

namespace lapisTracker;
use lapisLogger, lapisTrackerServices;

class PersistenceManager
{
   public function __construct(PersistService $ps, Logger $logger)
   { /** […] */ }

    public function persistPosition($coordinates, DateTime $time = null)
    {
      try {
         $this->ps->setCoordinates($coordinates);
         $this->ps->setTimeStamp($time);
         $this->ps->persist();
         $this->logger->log('Position stored successfully');

        } catch (PersistServiceException $e) {
           $this->logger->exception($e);
        }
    }
}
Dependency inversion
 principle
 Fundamental principle for OOD
 Encapsulate low level modules in abstractions
 Depend on abstractions / interfaces rather than
 implementations
Interface segregation
  principle (ISP)



„Make fine grained interfaces that
      are client specific.“
Where do
we start
<?php

namespace lapisTracker;
use lapisLogger, lapisTrackerServices;

class PersistenceManager
{
   public function __construct(PersistService $ps, Logger $logger)
   { /** […] */ }

    public function persistPosition($coordinates, DateTime $time = null)
    {
      try {
         $this->ps->setCoordinates($coordinates);
         $this->ps->setTimeStamp($time);
         $this->ps->persist();
         $this->logger->log('Position stored successfully');

        } catch (PersistServiceException $e) {
           $this->logger->exception($e);
        }
    }
}
How to do
it right
<?php

namespace lapisTracker;
use lapisLogger, lapisTrackerServices;

class PersistenceManager implements PersistenceManagerPosition
{
   public function __construct(PersistService $ps, Logger $logger)
   { /** […] */ }

    public function persistPosition($coordinates, DateTime $time = null)
    { /** […] */ }

    public function persistHeight($height, DateTime $time = null)
    { /** […] */ }

    public function persistLocation($height, DateTime $time = null)
    { /** […] */ }
}

interface PersistenceManagerPosition
{
   public function persistPosition($coordinates, DateTime $time = null);
}
<?php

namespace lapisTracker;
use lapisTrackerStructsPosition;

class Geolocation extends Tracker
{
   public function __construct(Parser $parser, PersistenceManagerPosition $pm)
   { /** […] */ }

    public function trackPosition(Position $position, DateTime $time = null)
    {
      try{
         $coordinates = $this->parser->parsePosition($position);
         $this->pm->persistPosition($coordinates, $time);

        } catch (PersistanceManagerException $e) {
            throw new TrackerException(
               'Unable to persist your position.', TrackerException::PersistError,
               $e
            );
         }
    }
}
Interface segregation
  principle
 Avoid „fat“ interfaces, stick to what's really
 needed
 Ask yourself „What do I want to archieve?“
 Be strict!
Open/Close principle (OCP)



  „You should be able to extend a
classes behavior, without modifying
                it.“
Open/Close principle (OCP)

 „It is the heard of object oriented design“
 Combines the other 4 principles
Where we started
Where we got
Questions
@lapistano

bastian.feder@liip.ch
PHP5.3 Powerworkshop

              New features of
              PHP5.3
              Best Pratices using
              OOP
              PHPUnit
              PHPDocumentor
License

 
     This set of slides and the source code included
     in the download package is licensed under the

Creative Commons Attribution-Noncommercial-
        Share Alike 2.0 Generic License


      http://creativecommons.org/licenses/by-nc-sa/2.0/deed.en

More Related Content

What's hot

Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of LithiumNate Abele
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolveXSolve
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data ObjectsWez Furlong
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Fabien Potencier
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5 Wildan Maulana
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in actionJace Ju
 
Internationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsInternationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsPierre MARTIN
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareKuan Yen Heng
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Workhorse Computing
 
Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsMark Baker
 
Building a Pluggable Plugin
Building a Pluggable PluginBuilding a Pluggable Plugin
Building a Pluggable PluginBrandon Dove
 

What's hot (20)

Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of Lithium
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data Objects
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
 
Agile database access with CakePHP 3
Agile database access with CakePHP 3Agile database access with CakePHP 3
Agile database access with CakePHP 3
 
Internationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsInternationalizing CakePHP Applications
Internationalizing CakePHP Applications
 
SOLID PRINCIPLES
SOLID PRINCIPLESSOLID PRINCIPLES
SOLID PRINCIPLES
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middleware
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
 
CakeFest 2013 keynote
CakeFest 2013 keynoteCakeFest 2013 keynote
CakeFest 2013 keynote
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Json perl example
Json perl exampleJson perl example
Json perl example
 
Solid principles
Solid principlesSolid principles
Solid principles
 
Building a Pluggable Plugin
Building a Pluggable PluginBuilding a Pluggable Plugin
Building a Pluggable Plugin
 

Viewers also liked

Viewers also liked (12)

Las TIC
Las TICLas TIC
Las TIC
 
The beautyandthebeast phpbat2010
The beautyandthebeast phpbat2010The beautyandthebeast phpbat2010
The beautyandthebeast phpbat2010
 
Php Documentor The Beauty And The Beast
Php Documentor The Beauty And The BeastPhp Documentor The Beauty And The Beast
Php Documentor The Beauty And The Beast
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Eclipse HandsOn Workshop
Eclipse HandsOn WorkshopEclipse HandsOn Workshop
Eclipse HandsOn Workshop
 
Why documentation osidays
Why documentation osidaysWhy documentation osidays
Why documentation osidays
 
Robert martin
Robert martinRobert martin
Robert martin
 
jQuery's Secrets
jQuery's SecretsjQuery's Secrets
jQuery's Secrets
 
SOLID Principles of Refactoring Presentation - Inland Empire User Group
SOLID Principles of Refactoring Presentation - Inland Empire User GroupSOLID Principles of Refactoring Presentation - Inland Empire User Group
SOLID Principles of Refactoring Presentation - Inland Empire User Group
 
Error handling in ASP.NET
Error handling in ASP.NETError handling in ASP.NET
Error handling in ASP.NET
 
Functional solid
Functional solidFunctional solid
Functional solid
 
Exception handling in asp.net
Exception handling in asp.netException handling in asp.net
Exception handling in asp.net
 

Similar to S.O.L.I.D Principles in PHP

PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overviewjsmith92
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Jason Lotito
 
Objects, Testing, and Responsibility
Objects, Testing, and ResponsibilityObjects, Testing, and Responsibility
Objects, Testing, and Responsibilitymachuga
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Fabien Potencier
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest UpdatesIftekhar Eather
 
Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Alena Holligan
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 
Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Damien Seguy
 
Demystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPDemystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPAlena Holligan
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8Alexei Gorobets
 
Architecture logicielle #3 : object oriented design
Architecture logicielle #3 : object oriented designArchitecture logicielle #3 : object oriented design
Architecture logicielle #3 : object oriented designJean Michel
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosDivante
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous phpWim Godden
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteLeonardo Proietti
 
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)Krzysztof Menżyk
 

Similar to S.O.L.I.D Principles in PHP (20)

PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overview
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13
 
Objects, Testing, and Responsibility
Objects, Testing, and ResponsibilityObjects, Testing, and Responsibility
Objects, Testing, and Responsibility
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)
 
Demystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPDemystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHP
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
Architecture logicielle #3 : object oriented design
Architecture logicielle #3 : object oriented designArchitecture logicielle #3 : object oriented design
Architecture logicielle #3 : object oriented design
 
OOP in PHP
OOP in PHPOOP in PHP
OOP in PHP
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
Oops in php
Oops in phpOops in php
Oops in php
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
Ch8(oop)
Ch8(oop)Ch8(oop)
Ch8(oop)
 
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
 

More from Bastian Feder

JQuery plugin development fundamentals
JQuery plugin development fundamentalsJQuery plugin development fundamentals
JQuery plugin development fundamentalsBastian Feder
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsBastian Feder
 
Introducing TDD to your project
Introducing TDD to your projectIntroducing TDD to your project
Introducing TDD to your projectBastian Feder
 
The Beauty and the Beast
The Beauty and the BeastThe Beauty and the Beast
The Beauty and the BeastBastian Feder
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)Bastian Feder
 
Debugging PHP with xDebug inside of Eclipse PDT 2.1
Debugging PHP with xDebug inside of Eclipse PDT 2.1Debugging PHP with xDebug inside of Eclipse PDT 2.1
Debugging PHP with xDebug inside of Eclipse PDT 2.1Bastian Feder
 
The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09Bastian Feder
 
Eclipse Pdt2.0 26.05.2009
Eclipse Pdt2.0 26.05.2009Eclipse Pdt2.0 26.05.2009
Eclipse Pdt2.0 26.05.2009Bastian Feder
 
Php Development With Eclipde PDT
Php Development With Eclipde PDTPhp Development With Eclipde PDT
Php Development With Eclipde PDTBastian Feder
 
Bubbles & Trees with jQuery
Bubbles & Trees with jQueryBubbles & Trees with jQuery
Bubbles & Trees with jQueryBastian Feder
 
Ajax hands on - Refactoring Google Suggest
Ajax hands on - Refactoring Google SuggestAjax hands on - Refactoring Google Suggest
Ajax hands on - Refactoring Google SuggestBastian Feder
 

More from Bastian Feder (14)

JQuery plugin development fundamentals
JQuery plugin development fundamentalsJQuery plugin development fundamentals
JQuery plugin development fundamentals
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
 
Introducing TDD to your project
Introducing TDD to your projectIntroducing TDD to your project
Introducing TDD to your project
 
The Beauty and the Beast
The Beauty and the BeastThe Beauty and the Beast
The Beauty and the Beast
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
 
Debugging PHP with xDebug inside of Eclipse PDT 2.1
Debugging PHP with xDebug inside of Eclipse PDT 2.1Debugging PHP with xDebug inside of Eclipse PDT 2.1
Debugging PHP with xDebug inside of Eclipse PDT 2.1
 
The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09
 
Eclipse Pdt2.0 26.05.2009
Eclipse Pdt2.0 26.05.2009Eclipse Pdt2.0 26.05.2009
Eclipse Pdt2.0 26.05.2009
 
Php Development With Eclipde PDT
Php Development With Eclipde PDTPhp Development With Eclipde PDT
Php Development With Eclipde PDT
 
Bubbles & Trees with jQuery
Bubbles & Trees with jQueryBubbles & Trees with jQuery
Bubbles & Trees with jQuery
 
Ajax hands on - Refactoring Google Suggest
Ajax hands on - Refactoring Google SuggestAjax hands on - Refactoring Google Suggest
Ajax hands on - Refactoring Google Suggest
 

Recently uploaded

Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 

Recently uploaded (20)

Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 

S.O.L.I.D Principles in PHP

  • 1. S.O.L.I.D Principles Bastian Feder OSIDays 2011, Bangalore bastian.feder@liip.ch 21st November 2011
  • 2. Me, myself & I PHP since 2001 Testing and Quality coach @ Liip Inc. Opensource addict PHP manual translations FluentDOM phpDox
  • 3. News from Uncle Bob Essential principles for software development & object oriented design (OOD). Robert C. Martin summarized those principles, but did not invent them.
  • 4. Which are these principles? Single responsibility principle Open/Close principle Liskov substitution principle Interface segregation principle Dependency inversion principle
  • 5. Geolocation Tracker „As a hiker I want to track where I walked and how much I climbed.“ „As a developer I want to be able to store the geo information on different devices.“ „As a developer I want to store the geo information in a unified format.“
  • 6. Single responsibility principle (SRP) „A class should have one, and only one, reason to change.“
  • 7. How to do it wrong
  • 8. <?php namespace lapisTracker; use lapisTrackerStructs; class Geolocation extends Tracker { public function trackPosition(Position $position) { list($langitude, $longitude, $altitude) = $this->extractCoordinatesFromPosition($position); $altitude = $this->convertFeetToMeter($altitude); $this->persistPosition($langitude, $longitude, $altitude, new DateTime()); } public function persistPosition( $langitude, $longitude, $altitude, DateTime $time) { try{ $conn = $this->getDatabaseConnection('write'); $conn->execute($this->generateQuery($langitude, $longitude, $altitude, $time)); } catch (Exception $e) { $this->logError($e->getMessage()); } } /** […] */ }
  • 9. How to do it right
  • 10. <?php namespace lapisTracker; use lapisTrackerStructsPosition; class Geolocation extends Tracker { public function __construct(Parser $parser, PersistenceManager $pm) { /** […] */ } public function trackPosition(Position $position, DateTime $time = null) { try { $coordinates = $this->parser->parsePosition($position); $this->pm->persistPosition($coordinates, $time); } catch (PersistanceManagerException $e) { throw new TrackerException( 'Unable to persist your position.', TrackerException::PersistError, $e ); } } }
  • 11. Single responsibility principle Simple to understand, very hard to get right. Separation of responsibilities / concerns One responsibility per class
  • 12. Liskov substitution principle (LSP) „Derived classes must be substitutable for their base classes.“
  • 14. <?php namespace lapisConverter; class Distance { const FACTOR = 0.3048; // 1 foot in meters public function feetToMeters($distance) { $this->verifyDistance($distance); return $distance * self::FACTOR; } public function metersToFeet($distance) { $this->verifyDistance($distance); return $distance / self::FACTOR; } protected function verifyDistance($distance) { if ($distance < 0) { throw new OutOfRangeException( 'Distance may not be lower than zero.', DistanceException::OutOfRange ); } } }
  • 15. How to do it wrong
  • 16. <?php namespace lapisConverterDistance; use lapisConverter; class NegativeDistance extends Distance { protected function verifyDistance($distance) { return TRUE; } }
  • 17. How to do it right
  • 18. <?php namespace lapisConverterDistance; use lapisConverter; class MaxDistance extends Distance { public function feetToMeters($distance) { $distance = parent::feetToMeters($distance); $this->verifyDistance($distance, 15000); return $distance; } protected function verifyDistance($distance, $max = 0) { if ($distance < 0) { $message = 'Distance may not be lower than the zero.'; } if ($max > 0 && $distance >= $max) { $message = 'Distance may not be greater than the maximum of ' . $max . '.'; } If (isset($message) { throw new OutOfRangeException($message, DistanceException::OutOfRange); } } }
  • 19. Liskov substitution principle Design by contract User must not distinguish between super- & subclasses Derived class must be more strict on output, but may handle the input less strict. Increases maintainability, robustness & resusability
  • 20. Dependency inversion principle (DIP) „Depend on abstractions, not on concretions.“
  • 21. How to do it wrong
  • 22. <?php namespace lapisTracker; use lapisTrackerStructsPosition; class PersistenceManager { public function __construct(Tracker $tracker) { /** […] */ } public function trackPosition(Position $position) { try { $this->tracker->trackPosition($position); $this->log('Position stored successfully'); } catch (TrackerException $e) { $this->log($e->getMessage()); } } protected function log($message) { $fh = fopen ('log.txt' , 'a'); fwrite($fh, $message); fclose($fh); } /** […] */ }
  • 23. How to do it right
  • 24. <?php namespace lapisTracker; use lapisLogger, lapisTrackerServices; class PersistenceManager { public function __construct(PersistService $ps, Logger $logger) { /** […] */ } public function persistPosition($coordinates, DateTime $time = null) { try { $this->ps->setCoordinates($coordinates); $this->ps->setTimeStamp($time); $this->ps->persist(); $this->logger->log('Position stored successfully'); } catch (PersistServiceException $e) { $this->logger->exception($e); } } }
  • 25. Dependency inversion principle Fundamental principle for OOD Encapsulate low level modules in abstractions Depend on abstractions / interfaces rather than implementations
  • 26. Interface segregation principle (ISP) „Make fine grained interfaces that are client specific.“
  • 28. <?php namespace lapisTracker; use lapisLogger, lapisTrackerServices; class PersistenceManager { public function __construct(PersistService $ps, Logger $logger) { /** […] */ } public function persistPosition($coordinates, DateTime $time = null) { try { $this->ps->setCoordinates($coordinates); $this->ps->setTimeStamp($time); $this->ps->persist(); $this->logger->log('Position stored successfully'); } catch (PersistServiceException $e) { $this->logger->exception($e); } } }
  • 29. How to do it right
  • 30. <?php namespace lapisTracker; use lapisLogger, lapisTrackerServices; class PersistenceManager implements PersistenceManagerPosition { public function __construct(PersistService $ps, Logger $logger) { /** […] */ } public function persistPosition($coordinates, DateTime $time = null) { /** […] */ } public function persistHeight($height, DateTime $time = null) { /** […] */ } public function persistLocation($height, DateTime $time = null) { /** […] */ } } interface PersistenceManagerPosition { public function persistPosition($coordinates, DateTime $time = null); }
  • 31. <?php namespace lapisTracker; use lapisTrackerStructsPosition; class Geolocation extends Tracker { public function __construct(Parser $parser, PersistenceManagerPosition $pm) { /** […] */ } public function trackPosition(Position $position, DateTime $time = null) { try{ $coordinates = $this->parser->parsePosition($position); $this->pm->persistPosition($coordinates, $time); } catch (PersistanceManagerException $e) { throw new TrackerException( 'Unable to persist your position.', TrackerException::PersistError, $e ); } } }
  • 32. Interface segregation principle Avoid „fat“ interfaces, stick to what's really needed Ask yourself „What do I want to archieve?“ Be strict!
  • 33. Open/Close principle (OCP) „You should be able to extend a classes behavior, without modifying it.“
  • 34. Open/Close principle (OCP) „It is the heard of object oriented design“ Combines the other 4 principles
  • 38. PHP5.3 Powerworkshop New features of PHP5.3 Best Pratices using OOP PHPUnit PHPDocumentor
  • 39. License  This set of slides and the source code included in the download package is licensed under the Creative Commons Attribution-Noncommercial- Share Alike 2.0 Generic License http://creativecommons.org/licenses/by-nc-sa/2.0/deed.en