BUT
YOU CAN STILL USE IT TO BUILD SOLID STUFF
(IF YOU KNOW HOW)
Slide 5
Slide 5 text
SO LET’S TALK ABOUT
THE HOW
Slide 6
Slide 6 text
QUALITIES OF
GOOD CODE
Slide 7
Slide 7 text
EASY TO CHANGE
EASY TO UNDERSTAND
EASY TO (RE)USE
~
HARD TO BREAK
Slide 8
Slide 8 text
“Always code as if the guy who ends up maintaining your code will be a
violent psychopath who knows where you live”
- probably John Woods
Slide 9
Slide 9 text
SHY CODE
Slide 10
Slide 10 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 11
Slide 11 text
ENCAPSULATION
“MODULES THAT DON’T REVEAL ANYTHING
UNNECESSARY TO OTHER MODULES”
NAMES THAT LIE
// neither of these is actually a locale
$this->locale = $locale->locale;
// does more than it says
public function getItem() {
// write to disk
}
Slide 37
Slide 37 text
EXTRACT METHOD
// before:
if (is_numeric($amount) && $amount > 0)
// after:
if ($this->isValidAmount($amount))
Slide 38
Slide 38 text
VALUE OBJECTS
$amount = new Amount($amount);
// throws exception if amount is invalid
Slide 39
Slide 39 text
CODE SAYS WHAT
COMMENTS SAY WHY
Slide 40
Slide 40 text
// set the patient’s clinic
$patient->setClinic($clinic);
// to register a patient, set the patient’s clinic
$patient->setClinic($clinic);
Slide 41
Slide 41 text
GOOD NAMING AND GOOD ABSTRACTIONS
BEAT GOOD COMMENTS
Slide 42
Slide 42 text
$clinic->registerPatient($patient);
Slide 43
Slide 43 text
PRINCIPLE OF LEAST ASTONISHMENT
(MINIMIZE THE NUMBER OF WTFS PER MINUTE)
Slide 44
Slide 44 text
“I REUSE CODE IF, AND ONLY IF, I NEVER
NEED TO LOOK AT THE SOURCE CODE”
~
UNCLE BOB
Slide 45
Slide 45 text
WELL-ABSTRACTED
GOOD OUTWARD-FACING API
DECOUPLED
Slide 46
Slide 46 text
NAMESPACES
PREVENTING NAMING COLLISIONS
SINCE PHP 5.3
Slide 47
Slide 47 text
COMPOSER
Slide 48
Slide 48 text
OPEN SOURCE VIA GITHUB/PACKAGIST
PRIVATE REPOSITORIES IN COMPOSER.JSON
TORAN PROXY
Slide 49
Slide 49 text
ADDED BONUS
AUTOLOADING FOR INTERNAL CLASSES
(THIS ALONE MAKES COMPOSER WORTH USING)
Slide 50
Slide 50 text
PHPDOC DOCBLOCKS
IDE USERS LOVE THIS
Slide 51
Slide 51 text
”SIMPLICITY IS PREREQUISITE FOR
RELIABILITY.”
~
EDSGER DIJKSTRA
Slide 52
Slide 52 text
”Rely only on reliable things”
- The Pragmatic Programmer
Slide 53
Slide 53 text
NOT A RELIABLE THING:
THE PHP TYPE SYSTEM
Slide 54
Slide 54 text
if (! $amount) {
// do something
}
// $amount can actually be 0, “0”, “”, null or false for this to be true
Slide 55
Slide 55 text
if ($amount == 0) {
// do something
}
// $amount can now still be 0, “0” or false for this to be true
Slide 56
Slide 56 text
if ($amount === 0) {
// do something
}
// this will only evaluate to true when $amount is actually the number 0
Slide 57
Slide 57 text
“CRASH, DON’T TRASH”
~
THE PRAGMATIC PROGRAMMER
Slide 58
Slide 58 text
DO NOT PROGRAM BY COINCIDENCE
Slide 59
Slide 59 text
”TEST YOUR SOFTWARE, OR YOUR USERS
WILL”
~
THE PRAGMATIC PROGRAMMER
Slide 60
Slide 60 text
PHPUNIT
PHPSPEC
CODECEPTION
BEHAT
Slide 61
Slide 61 text
“WHEN YOU AREN’T AFRAID TO CHANGE
YOUR CODE, YOU WILL CLEAN IT”
~
UNCLE BOB
Slide 62
Slide 62 text
LANGUAGE FEATURES
TYPEHINTING
VISIBILITY (PRIVATE BY DEFAULT)
EXCEPTIONS
Slide 63
Slide 63 text
CLOSING NOTES
Slide 64
Slide 64 text
LEARNING ABOUT THIS STUFF IS EASY
DOING IT RIGHT IS HARD
Slide 65
Slide 65 text
“TO A MAN WITH A HAMMER, EVERYTHING
LOOKS LIKE A NAIL.”
~
ABRAHAM MASLOW
Slide 66
Slide 66 text
NONE OF THESE IDEAS ARE NEW
(IN FACT, MOST ARE PRETTY OLD)
Slide 67
Slide 67 text
“THE MORE I LEARN, THE MORE I REALIZE
HOW MUCH I DON’T KNOW”
~
ALBERT EINSTEIN
Slide 68
Slide 68 text
BOOKS
Growing Object-Oriented Software, Guided By Tests
The Pragmatic Programmer
Domain-Driven Design
Patterns of Enterprise Application Architecture
Clean Code
Slide 69
Slide 69 text
VIDEOS
Models and Service Layers; Hemoglobin and Hobgoblins
(https://www.youtube.com/watch?v=3uV3ngl1Z8g)
Unbreakable Domain Models
(https://www.youtube.com/watch?v=ZJ63ltuwMaE)
The Framework As An Implementation Detail
(https://www.youtube.com/watch?v=0L_9NutiJlc)
Slide 70
Slide 70 text
PODCASTS
Elephant in the Room (http://elephantintheroom.io)
Slide 71
Slide 71 text
QUESTIONS?
Slide 72
Slide 72 text
PLUG TIME
WERKENBIJMIJNDOMEIN.NL
Slide 73
Slide 73 text
BONUS STAGE
SOLID PRINCIPLES
Slide 74
Slide 74 text
“A CLASS SHOULD HAVE ONE, AND ONLY ONE,
REASON TO CHANGE.”
~
SOLID PRINCIPLE #1
(SINGLE RESPONSIBILITY PRINCIPLE)
Slide 75
Slide 75 text
“A CLASS SHOULD BE OPEN FOR EXTENSION,
BUT CLOSED FOR MODIFICATION”
~
SOLID PRINCIPLE #2
(OPEN-CLOSED PRINCIPLE)
Slide 76
Slide 76 text
”CHANGE WHAT A CLASS DOES, BUT NOT
WHAT IT IS”
~
KONSTANTIN KUDRYASHOV
Slide 77
Slide 77 text
“SUBCLASSES MUST BE SUBSTITUTABLE FOR
THEIR BASE CLASSES”
~
SOLID PRINCIPLE #3
(LISKOV SUBSTITUTION PRINCIPLE)
Slide 78
Slide 78 text
”NEVER FORCE CLASSES TO IMPLEMENT
METHODS THAT THEY DO NOT USE”
~
SOLID PRINCIPLE #4
(INTERFACE SEGREGATION PRINCIPLE)
Slide 79
Slide 79 text
interface DoesAllTheThings {
public function save(Soul $soul);
public function addOneAndOne(One $one, One $one);
public function shave(Yak $yak);
}
Slide 80
Slide 80 text
class DefaultCalculator implements Calculator {
public function addOneAndOne(One $one, One $one)
{
return new Two;
}
}
Slide 81
Slide 81 text
class DoesAllTheThings implements SoulSaver, Calculator, YakShaver {
// can still do all the things
}
Slide 82
Slide 82 text
“DEPEND ON ABSTRACTIONS, NOT ON
CONCRETIONS”
~
SOLID PRINCIPLE #5
(DEPENDENCY INVERSION PRINCIPLE)