Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Object-georienteerd Programmeren
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Stefan Koopmanschap
June 27, 2014
Programming
0
240
Object-georienteerd Programmeren
The slides for the OO-training during the Techademy trainingday on June 27th
Stefan Koopmanschap
June 27, 2014
Tweet
Share
More Decks by Stefan Koopmanschap
See All by Stefan Koopmanschap
How to make good decisions with a happy team (SymfonyCon 2025)
skoop
0
58
PHP Kitchen Nightmares (PHP.FRL)
skoop
0
73
Sustainable open source contributions in your business (CakeFest 2024)
skoop
0
98
Domain-Driven Design: The Basics (SymfonyCon 2023, Brussels)
skoop
0
220
Domain-Driven Design: The Basics (Cakefest)
skoop
0
230
PHP Kitchen Nightmares
skoop
0
67
Domain Driven Design - The Basics (TechTuesday XXL, Tilburg)
skoop
0
110
7 Lessons You Can Learn From Disney Movies (SymfonyCon 2022)
skoop
0
290
Mental Health in the Workplace (SymfonyCon 2019, Amsterdam)
skoop
0
710
Other Decks in Programming
See All in Programming
生成AIを使ったコードレビューで定性的に品質カバー
chiilog
1
260
AIフル活用時代だからこそ学んでおきたい働き方の心得
shinoyu
0
130
AI巻き込み型コードレビューのススメ
nealle
1
150
今から始めるClaude Code超入門
448jp
8
8.6k
メルカリのリーダビリティチームが取り組む、AI時代のスケーラブルな品質文化
cloverrose
2
510
それ、本当に安全? ファイルアップロードで見落としがちなセキュリティリスクと対策
penpeen
7
3.8k
dchart: charts from deck markup
ajstarks
3
990
組織で育むオブザーバビリティ
ryota_hnk
0
170
OSSとなったswift-buildで Xcodeのビルドを差し替えられるため 自分でXcodeを直せる時代になっている ダイアモンド問題編
yimajo
3
610
AI & Enginnering
codelynx
0
110
2026年 エンジニアリング自己学習法
yumechi
0
130
「ブロックテーマでは再現できない」は本当か?
inc2734
0
910
Featured
See All Featured
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
1
1.4k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
730
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
450
Designing Powerful Visuals for Engaging Learning
tmiket
0
230
Evolving SEO for Evolving Search Engines
ryanjones
0
120
Fireside Chat
paigeccino
41
3.8k
Agile that works and the tools we love
rasmusluckow
331
21k
It's Worth the Effort
3n
188
29k
BBQ
matthewcrist
89
10k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
88
Unsuck your backbone
ammeep
671
58k
Transcript
Object'georienteerd.programmeren Techademy,*27-06-2014
De#onderwerpen
De#onderwerpen • Wat%is%OO?
De#onderwerpen • Wat%is%OO? • De%basistermen
De#onderwerpen • Wat%is%OO? • De%basistermen • SOLID
De#onderwerpen • Wat%is%OO? • De%basistermen • SOLID • Zelf%refactoren
De#onderwerpen • Wat%is%OO? • De%basistermen • SOLID • Zelf%refactoren •
Hoe%nu%verder?
Een$stukje$geschiedenis
Een$stukje$geschiedenis • Eind&jaren&'50,&begin&jaren&'60&bij&MIT
Een$stukje$geschiedenis • Eind&jaren&'50,&begin&jaren&'60&bij&MIT • Oude&versies&van&PHP&hadden&niet&echt&een&object&model
Een$stukje$geschiedenis • Eind&jaren&'50,&begin&jaren&'60&bij&MIT • Oude&versies&van&PHP&hadden&niet&echt&een&object&model • 13&juli&2004&veranderde&dit
Wat$is$OO?
Wat$is$OO? • De$tegenhanger$van$"Procedureel/Func5onal$Programming"
Wat$is$OO? • De$tegenhanger$van$"Procedureel/Func5onal$Programming" • Je$werkt$met$objecten
Wat$is$OO? • De$tegenhanger$van$"Procedureel/Func5onal$Programming" • Je$werkt$met$objecten • Abstrac5e$van$func5onaliteit$en$data
Wat$is$OO? <?php mysql_connect('localhost', 'root', 'secret'); mysql_select_db('foo'); echo "<h1>Foo Bar &
Co</h1><br />"; $sql = "SELECT * from bar where category='".$_GET['cat']."'"; $result = mysql_query($sql); while($row = mysql_fetch_assoc($result)) { $name = format_name($row['name]); echo $name."<br />"; } echo "<sub>(c) 2014 Foo Bar & Co</sub>";
Wat$is$OO?
Wat$is$OO? • Configura*e,in,je,code
Wat$is$OO? • Configura*e,in,je,code • Database,logica
Wat$is$OO? • Configura*e,in,je,code • Database,logica • Request/inputa:andeling,
Wat$is$OO? • Configura*e,in,je,code • Database,logica • Request/inputa:andeling • Weergavelogica
Wat$is$OO? <?php $config = new Config('/path/to/configfile.php'); $request = new Request();
$response = new Response(); $view = new View('/path/to/barlisttemplate.php'); $db = new Db($config->get('dbhost'), $config->get('dbuser'), $config->get('dbpassword'), $config->get('dbname')); $barRepository = new BarRepository($db); $bars = $barRepository->getByCategory($request->get('cat')); $output = $view->parse($bars); $request->send($output);
De#basistermen Laten&we&beginnen&bij&het&begin
Class <?php class Db { }
Object <?php $db = new Db();
Func%on <?php function doSomething() { }
Method <?php class Db { public function query() { }
}
Magic&Methods <?php class User { public function __toString() { return
$this->getName(); } }
Magic&Methods • __construct() • __destruct() • __call() • __callSta1c() •
__get() • __set() • __isset()
Magic&Methods • __unset() • __sleep() • __wakeup() • __toString() •
__invoke() • _setstate() • __clone()
Constructor <?php class Db { public function __construct($host, $user, $pass,
$name) { $this->connection = mysql_connect($host, $user, $pass); mysql_select_db($name, $this->connection); } }
Sta$c <?php class Foo { static public function bar() {
return 'no instance'; } } echo Foo::bar(); // echo's "no instance"
Variable <?php $foo = 'bar';
Property <?php class Db { private $connection; public function __construct()
{ // etc } }
Access%modifier%(visibility) <?php class Db { private $connection; public function __construct($host,
$user, $pass, $name) { $this->connection = $this->connect($host, $user, $pass); $this->selectDb($name); } protected function connect($host, $user, $pass) { return mysql_connect($host, $user, $pass); } protected function selectDb($name) { mysql_select_db($name, $this->connection); } }
Abstrac(e Het$lostrekken$van$logica$naar$aparte$stukken$code Eigenlijk)precies)wat)ik)je)net)heb)laten)zien
Encapsula)e Het$encapsuleren$van$de$specifieke$implementa3e$van$een$taak <?php class Db { protected function connect($host, $user,
$pass) { return mysql_connect($host, $user, $pass); } }
Inheritance <?php class Mysql extends Db { protected function connect($host,
$user, $pass) { return mysql_connect($host, $user, $pass); } // etc } <?php class Postgres extends Db { protected function connect($host, $user, $pass) { return pg_connect("host=".$host." user=".$user." password=".$pass); } // etc }
Composi'e Het$samenstellen$van$func.onaliteit$door$middel$van$meerdere$ objecten <?php $db = new Db($config->get('dbhost'), $config->get('dbuser'), $config->get('dbpassword'),
$config->get('dbname')); $barRepository = new $barRepository($db);
Interface Het$maken$van$een$contract$waarnaar$geprogrammeerd$moet$ worden <?php interface DbInterface { public function __construct($host,
$user, $pass, $name); public function query($sql); } class Mysql implements DbInterface { protected function connect($host, $user, $pass) { return mysql_connect($host, $user, $pass); } // etc }
Abstracte)class Een$abstracte$class$kan$niet$worden$geinstan2eerd$omdat$deze$nog$ niet$volledig$klaar$is <?php abstract class Db { private $connection;
public function __construct($host, $user, $pass, $name) { $this->connection = $this->connect($host, $user, $pass); $this->selectDb($name); } abstract protected function connect($host, $user, $pass); abstract protected function selectDb($name); } class Mysql extends Db implements DbInterface { protected function connect($host, $user, $pass) { return mysql_connect($host, $user, $pass); } // etc }
Type%hin)ng Vertel&wat&voor&soort¶meter&je&verwacht <?php class BarRepository { public function __construct(Db $db)
{ // etc } }
Type%hin)ng <?php class BarRepository { public function __construct(DbInterface $db) {
// etc } }
SOLID • Single'Responsibility'Principle
Single'Responsibility'Principle • Iedere&class&hee,&maar&één&enkele&verantwoordelijkheid
Single'Responsibility'Principle • Iedere&class&hee,&maar&één&enkele&verantwoordelijkheid • Alle&implementa9elogica&voor&deze&verantwoordelijk&is& geencapsuleerd
Single'Responsibility'Principle • Iedere&class&hee,&maar&één&enkele&verantwoordelijkheid • Alle&implementa9elogica&voor&deze&verantwoordelijk&is& geencapsuleerd • Onder&water&kan&de&class&voor&gerelateerde&logica&weer&andere& classes&aanroepen
SOLID • Single'Responsibility'Principle • Open/Closed'Principle
Open/Closed+Principle • Iedere&class&moet&open&staan&voor&uitbreiding,&maar&gesloten& voor&aanpassing
Open/Closed+Principle • Iedere&class&moet&open&staan&voor&uitbreiding,&maar&gesloten& voor&aanpassing • Zorg&dat&zo&veel&mogelijk&logica&protected&is,&alleen&hele& specifieke&dingen&private
Open/Closed+Principle • Iedere&class&moet&open&staan&voor&uitbreiding,&maar&gesloten& voor&aanpassing • Zorg&dat&zo&veel&mogelijk&logica&protected&is,&alleen&hele& specifieke&dingen&private • Gebruik&van&het&"final"&keyword&kan&ook&helpen&voor&(public)& methodes
Open/Closed+Principle • Iedere&class&moet&open&staan&voor&uitbreiding,&maar&gesloten& voor&aanpassing • Zorg&dat&zo&veel&mogelijk&logica&protected&is,&alleen&hele& specifieke&dingen&private • Gebruik&van&het&"final"&keyword&kan&ook&helpen&voor&(public)& methodes
• Extenden&is&makkelijk
Open/Closed+Principle • Iedere&class&moet&open&staan&voor&uitbreiding,&maar&gesloten& voor&aanpassing • Zorg&dat&zo&veel&mogelijk&logica&protected&is,&alleen&hele& specifieke&dingen&private • Gebruik&van&het&"final"&keyword&kan&ook&helpen&voor&(public)& methodes
• Extenden&is&makkelijk • De&code&aanpassen&is&dan&niet&nodig
SOLID • Single'Responsibility'Principle • Open/Closed'Principle • Liskov'Subs9tu9on'Principle
Liskov'Subs+tu+on'Principle • Classes'die'overerven'van'een'basisclass'moeten'die'basisclass' kunnen'vervangen
Liskov'Subs+tu+on'Principle • Classes'die'overerven'van'een'basisclass'moeten'die'basisclass' kunnen'vervangen • Als'new BarRepository($db);'werkt,'moet'new BarRepository($mysql)'zonder'aanpassing'ook'werken'
Liskov'Subs+tu+on'Principle • Classes'die'overerven'van'een'basisclass'moeten'die'basisclass' kunnen'vervangen • Als'new BarRepository($db);'werkt,'moet'new BarRepository($mysql)'zonder'aanpassing'ook'werken' • Stel'dat'we'ook'een'MongoDB'class'hebben'die'Db'extend,'dan'
zal'dit'geen'Liskov'zijn
SOLID • Single'Responsibility'Principle • Open/Closed'Principle • Liskov'Subs9tu9on'Principle • Interface'Segrega9on'Principle
Interface)Segrega,on)Principle Een$specifieke$func-onaliteit$hoort$alleen$maar$kennis$te$hebben$ van$methodes$voor$die$func-onaliteit
Interface)Segrega,on)Principle Een$specifieke$func-onaliteit$hoort$alleen$maar$kennis$te$hebben$ van$methodes$voor$die$func-onaliteit • In$plaats$van$1$database$class$die$zowel$Mysql,$Postgres$en$ Oracle$doet$heb$je$aparte$classes
Interface)Segrega,on)Principle Een$specifieke$func-onaliteit$hoort$alleen$maar$kennis$te$hebben$ van$methodes$voor$die$func-onaliteit • In$plaats$van$1$database$class$die$zowel$Mysql,$Postgres$en$ Oracle$doet$heb$je$aparte$classes • Naar$buiten$toe$een$consistente$API$aanbieden
SOLID • Single'Responsibility'Principle • Open/Closed'Principle • Liskov'Subs9tu9on'Principle • Interface'Segrega9on'Principle •
Dependency'Inversion'Principle
Dependency(Inversion(Principle Een$module$dient$geen$harde$a0ankelijkheden$te$hebben$van$ andere$modules
Dependency(Inversion(Principle Een$module$dient$geen$harde$a0ankelijkheden$te$hebben$van$ andere$modules • In$PHP$vooral$populair$via$Dependency$Injec5on
Dependency(Inversion(Principle Een$module$dient$geen$harde$a0ankelijkheden$te$hebben$van$ andere$modules • In$PHP$vooral$populair$via$Dependency$Injec5on • Sommige$frameworks$gebruiken$hiervoor$een$ServiceLocator
Dependency(Inversion(Principle Een$module$dient$geen$harde$a0ankelijkheden$te$hebben$van$ andere$modules • In$PHP$vooral$populair$via$Dependency$Injec5on • Sommige$frameworks$gebruiken$hiervoor$een$ServiceLocator • Zorgt$ook$voor$een$betere$testbaarheid$van$je$code
Dependency(Inversion(Principle Een$module$dient$geen$harde$a0ankelijkheden$te$hebben$van$ andere$modules • In$PHP$vooral$populair$via$Dependency$Injec5on • Sommige$frameworks$gebruiken$hiervoor$een$ServiceLocator • Zorgt$ook$voor$een$betere$testbaarheid$van$je$code •
Leunt$zwaar$op$het$gebruik$van$interfaces$om$bepaalde$ "contracten"$vast$te$leggen
Excep&ons
Excep&ons • Een%speciaal%soort%object
Excep&ons • Een%speciaal%soort%object • Als%er%iets%mis%gaat%kan%deze%worden%"gegooid"
Excep&ons • Een%speciaal%soort%object • Als%er%iets%mis%gaat%kan%deze%worden%"gegooid" • Dit%kan%hogerop%in%de%code%worden%"opgevangen"
Excep&ons • Een%speciaal%soort%object • Als%er%iets%mis%gaat%kan%deze%worden%"gegooid" • Dit%kan%hogerop%in%de%code%worden%"opgevangen" • Liefst%een%zo%specifiek%mogelijke%excep@on
Excep&ons <?php class Db { public function connect($host, $user, $pass)
{ if ($user == '') { throw new InvalidArgumentException('Username may not be empty'); } } }
Excep&ons <?php $db = new Db(); try { $db->connect('localhost', '',
'pass'); } catch (InvalidArgumentException $e) { // handle specifically the invalid argument exceptions } catch (Exception $e) { // handle all other exceptions }
Namespaces
Namespaces • Zorgen(voor(extra(structuur(in(de(code
Namespaces • Zorgen(voor(extra(structuur(in(de(code • Zorgt(ervoor(dat(je(meerdere(classes(met(dezelfde(naam(kan( hebben
Namespaces • Zorgen(voor(extra(structuur(in(de(code • Zorgt(ervoor(dat(je(meerdere(classes(met(dezelfde(naam(kan( hebben • Vroeger:(ZendSearchLuceneSearchQuery_Term
Namespaces • Zorgen(voor(extra(structuur(in(de(code • Zorgt(ervoor(dat(je(meerdere(classes(met(dezelfde(naam(kan( hebben • Vroeger:(ZendSearchLuceneSearchQuery_Term • Nu:(Zend\Search\Lucene\Search\Query\Term
Namespaces • Zorgen(voor(extra(structuur(in(de(code • Zorgt(ervoor(dat(je(meerdere(classes(met(dezelfde(naam(kan( hebben • Vroeger:(ZendSearchLuceneSearchQuery_Term • Nu:(Zend\Search\Lucene\Search\Query\Term
• In(je(code:(Term
Namespaces <?php namespace Database; class BaseDb { // etc }
Namespaces <?php namespace Database\Driver; use Database\BaseDb as Db; class Mysql
extends Db { // etc }
Namespaces h"p:/ /www.php(fig.org/psr/psr(0/
Zelf%refactoren Nu#gaan#jullie#zelf#aan#de#slag h"ps:/ /github.com/Techademy/Object7Oriented7Programming • Zorg&voor&een&goede&scheiding • Zorg&voor&zo&min&mogelijk&harde&a5ankelijkheden • De&output&van&voor&en&na&moet&iden:ek&zijn
• BONUS:&Schrijf&1&of&meer&unit&tests&met&PHPUnit
Hoe$nu$verder? • Best&prac+ces:&Gebruik&design&pa5erns
Hoe$nu$verder? • Best&prac+ces:&Gebruik&design&pa5erns • Refactor&je&eigen&code
Hoe$nu$verder? • Best&prac+ces:&Gebruik&design&pa5erns • Refactor&je&eigen&code • Lezen!&Er&zijn&veel&boeken&over&dit&onderwerp
Hoe$nu$verder? • Best&prac+ces:&Gebruik&design&pa5erns • Refactor&je&eigen&code • Lezen!&Er&zijn&veel&boeken&over&dit&onderwerp • Gebruik&Open&Source:&Veel&frameworks&en&libraries
Hoe$nu$verder? • Best&prac+ces:&Gebruik&design&pa5erns • Refactor&je&eigen&code • Lezen!&Er&zijn&veel&boeken&over&dit&onderwerp • Gebruik&Open&Source:&Veel&frameworks&en&libraries •
Schrijf&zo&veel&mogelijk&tests:&Zorgt&voor&beter&opgeze5e&code
Feedback h"ps:/ /joind.in/11407