• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Solid principles
 

Solid principles

on

  • 1,482 views

Early in year 2000 Robert C. Martin, aka "Uncle Bob", introduced his thoughts in an article about some of five basic principles on object oriented programming to the open world. What he probably did ...

Early in year 2000 Robert C. Martin, aka "Uncle Bob", introduced his thoughts in an article about some of five basic principles on object oriented programming to the open world. What he probably did not expect was, that this 5 principles became the standard for object oriented programming.
This Talk is about those principles: Single responsibility, Open/close, Liskov substitution, Interface segregation, and Dependency inversion, or shorter S.O.L.I.D. principles. It will give you an introduction about these principles, their meaning, and where they should be recognized and applied. Examples from my daily work will show you the practical aspects of those principles.

Statistics

Views

Total Views
1,482
Views on SlideShare
1,482
Embed Views
0

Actions

Likes
1
Downloads
25
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Solid principles Solid principles Presentation Transcript

    • S.O.L.I.D PrinciplesBastian Feder OSIDays 2011, Bangalorebastian.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 Iwalked and how much I climbed.“„As a developer I want to be able tostore the geo information on differentdevices.“„As a developer I want to store the geoinformation in a unified format.“
    • Single responsibility principle (SRP)„A class should have one, and only one, reason to change.“
    • How to doit wrong
    • <?phpnamespace 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 doit right
    • <?phpnamespace 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 dowe start
    • <?phpnamespace 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 doit wrong
    • <?phpnamespace lapisConverterDistance;use lapisConverter;class NegativeDistance extends Distance{ protected function verifyDistance($distance) { return TRUE; }}
    • How to doit right
    • <?phpnamespace 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 doit wrong
    • <?phpnamespace 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 doit right
    • <?phpnamespace 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 dowe start
    • <?phpnamespace 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 doit right
    • <?phpnamespace 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);}
    • <?phpnamespace 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 whats really needed Ask yourself „What do I want to archieve?“ Be strict!
    • Open/Close principle (OCP) „You should be able to extend aclasses 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@lapistanobastian.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 theCreative Commons Attribution-Noncommercial- Share Alike 2.0 Generic License http://creativecommons.org/licenses/by-nc-sa/2.0/deed.en