// neither of these is actually a locale
$this->locale = $locale->locale;
Slide 23
Slide 23 text
COMMENT ALL THE THINGS
(WELL, NOT ALL THE THINGS...)
Slide 24
Slide 24 text
CODE SAYS WHAT
COMMENTS SAY WHY
Slide 25
Slide 25 text
// set the patient’s clinic
$patient->setClinic($clinic);
// ORLY?
Slide 26
Slide 26 text
// to register a patient, set the patient’s clinic
$patient->setClinic($clinic);
Slide 27
Slide 27 text
GOOD NAMING AND GOOD
ABSTRACTIONS BEAT
GOOD COMMENTS
Slide 28
Slide 28 text
$clinic->registerPatient($patient);
Slide 29
Slide 29 text
PRINCIPLE OF LEAST ASTONISHMENT
(MINIMIZE THE NUMBER OF WTFS PER MINUTE)
Slide 30
Slide 30 text
PHPDOC ALL THE THINGS
CLASSES, VARIABLES, METHODS, ARGUMENTS
Slide 31
Slide 31 text
/**
* If what this method does can not be made obvious from
* its name, explain it here.
*
* @param string $firstname
* @return void
*/
public function changeFirstName($firstName)
{
// code
}
Slide 32
Slide 32 text
WHY BOTHER IF PHP DOES
NOT ENFORCE THIS?
COMMUNICATES INTENT
WORKS GREAT WITH IDES
Slide 33
Slide 33 text
“Shy code - modules that don’t reveal anything unnecessary to other
modules and that don’t rely on other modules’ implementations”
- The Pragmatic Programmer
Slide 34
Slide 34 text
WHY DECOUPLING?
ISOLATES CHANGES
MAKES YOUR CODE MORE FLEXIBLE
ENCOURAGES ABSTRACTION
Slide 35
Slide 35 text
”Modules that don’t reveal anything unnecessary to other modules”
ENCAPSULATION
SINGLE RESPONSIBILITY PRINCIPLE
”A class should have one, and only one, reason to change.”
Slide 97
Slide 97 text
”Every class, or similar structure, should have only one job to do.”
- Richard Carr
Slide 98
Slide 98 text
ASK YOURSELF
“What responsibilities does this piece of code have?”
Slide 99
Slide 99 text
$user = new User($userName, $password, $firstName, $lastName, $email);
$user->save();
// later on...
$user->login($userName, $password);
Slide 100
Slide 100 text
CONTAIN LOGIN CREDENTIALS
CONTAIN PERSONAL INFORMATION
STORE TO DATABASE
ACCESS MANAGEMENT
Slide 101
Slide 101 text
USER CLASS
CUSTOMER CLASS
USERSTORE / CUSTOMERSTORE CLASSES
AUTHENTICATIONMANAGER CLASS
Slide 102
Slide 102 text
$userAccount = new UserAccount($userName, $password);
$authenticationManager->register($userAccount);
$customer = new Customer($firstName, $lastName, $email);
$customer->linkUserAccount($userAccount);
$customerService->register($customer);
$authenticationService->login($userName, $password)
Slide 103
Slide 103 text
OPEN-CLOSED PRINCIPLE
“A class should be open for extension, but closed for modification”
Slide 104
Slide 104 text
public function ship(Product $product, $shippingMethod)
{
switch ($shippingmethod) {
case shipping::shipping_default:
$this->defaultshipping($product);
break;
case shipping::shipping_priority:
$this->priorityshipping($product);
break;
}
}
Slide 105
Slide 105 text
public function addShippingMethod(ShippingMethodInterface $method, $identifier)
{
$this->shippingMethods[$identifier] = $method;
}
public function ship(Product $product, $shippingMethodIdentifier)
{
$shippingMethod = $this->shippingMethods[$shippingMethodIdentifier];
$shippingMethod->ship($product);
}
Slide 106
Slide 106 text
LISKOV SUBSTITUTION PRINCIPE
”Subclasses must be substitutable for their base classes.”
Slide 107
Slide 107 text
“Any implementation of an abstraction (interface) should be
substitutable in any place that the abstraction is accepted”
- Jeffrey Way
Slide 108
Slide 108 text
interface VehicleInterface
{
public function driveTo(Destination $destination);
}
Slide 109
Slide 109 text
class Boat implements VehicleInterface
{
public function driveTo(Destination $destination)
{
// start driving
}
}
Slide 110
Slide 110 text
class Car implements VehicleInterface
{
public function driveTo(Destination $destination)
{
// start driving
}
public function swapTires(TyreTypeInterface $tyreType)
{
// swap tyres
}
}
Slide 111
Slide 111 text
/** @var VehicleInterface $vehicle */
$vehicle->swapTyres($tyreType);
// Car: works
// Boat: Method ‘swapTires’ not found in class Boat
Slide 112
Slide 112 text
INTERFACE SEGREGATION PRINCIPLE
”Never force classes to implement methods that they do not use”
Slide 113
Slide 113 text
interface VehicleInterface
{
public function driveTo(Destination $destination);
public function swapTires(TyreTypeInterface $tyreType);
}
Slide 114
Slide 114 text
class Boat implements VehicleInterface
{
public function driveTo(Destination $destination)
{
// start driving
}
public function swapTires(TyreTypeInterface $tyreType)
{
throw new BoatHasNoWheelsException();
}
}
Slide 115
Slide 115 text
interface VehicleInterface
{
public function driveTo(Destination $destination);
}
interface WheeledVehicleInterface
{
public function swapTires(TyreTypeInterface $tyreType);
}
Slide 116
Slide 116 text
class Car implements VehicleInterface, WheeledVehicleInterface
Slide 117
Slide 117 text
class Boat implements VehicleInterface, BoatInterface
Slide 118
Slide 118 text
DEPENDENCY INVERSION PRINCIPE
”Depend on abstractions, not on concretions.”
Slide 119
Slide 119 text
class StoreHouse
{
private $supplier;
public function __construct(FooBarInc $supplier)
{
$this->supplier = $supplier;
}
}
Slide 120
Slide 120 text
class StoreHouse
{
private $supplier;
public function __construct(SupplierInterface $supplier)
{
$this->supplier = $supplier;
}
}
Slide 121
Slide 121 text
class FooBarIncSupplier implements SupplierInterface
{
public function order(Product $product)
{
$orderId = $this->fooBarInc->createProductOrder();
$this->fooBarInc->addProductToOrder($orderId);
}
}
Slide 122
Slide 122 text
QUESTIONS?
Slide 123
Slide 123 text
READING LIST
Patterns of Enterprise Application Architecture - Martin Fowler
Clean Code - Robert C. Martin
Growing Object-Oriented Software, Guided By Tests (the GOOS book) -
Steve Freeman & Nat Pryce
The Pragmatic Programmer - Dave Thomas & Andy Hunt
Slide 124
Slide 124 text
VIDEOS
Models and Service Layers; Hemoglobin and Hobgoblins - Ross Tuck
(https://www.youtube.com/watch?v=3uV3ngl1Z8g)
Unbreakable Domain Models - Mathias Verraes (https://
www.youtube.com/watch?v=ZJ63ltuwMaE)
The Framework As An Implementation Detail (https://
www.youtube.com/watch?v=0L_9NutiJlc)
Slide 125
Slide 125 text
PODCASTS
Elephant in the Room (http://elephantintheroom.io)