The document discusses the SOLID principles of object-oriented design:
1. The Single Responsibility Principle states that a class should have one, and only one, reason to change.
2. The Open/Closed Principle states that software entities should be open for extension, but closed for modification.
3. The Liskov Substitution Principle states that derived classes must be substitutable for their base classes.
4. The Interface Segregation Principle states that interfaces should be client specific.
5. The Dependency Inversion Principle states that high level modules should not depend on low level modules but on abstractions.
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.“
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
);
}
}
}
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
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.“
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