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
Stefan Koopmanschap
June 27, 2014
Programming
260
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Object-georienteerd Programmeren
The slides for the OO-training during the Techademy trainingday on June 27th
Stefan Koopmanschap
June 27, 2014
More Decks by Stefan Koopmanschap
See All by Stefan Koopmanschap
How to make good decisions with a happy team (SymfonyCon 2025)
skoop
0
98
PHP Kitchen Nightmares (PHP.FRL)
skoop
0
100
Sustainable open source contributions in your business (CakeFest 2024)
skoop
0
130
Domain-Driven Design: The Basics (SymfonyCon 2023, Brussels)
skoop
0
250
Domain-Driven Design: The Basics (Cakefest)
skoop
0
270
PHP Kitchen Nightmares
skoop
0
82
Domain Driven Design - The Basics (TechTuesday XXL, Tilburg)
skoop
0
130
7 Lessons You Can Learn From Disney Movies (SymfonyCon 2022)
skoop
0
310
Mental Health in the Workplace (SymfonyCon 2019, Amsterdam)
skoop
0
750
Other Decks in Programming
See All in Programming
音楽のための関数型プログラミング言語mimiumにおける多段階計算の活用
tomoyanonymous
1
360
アルゴリズムは何を圧縮しているのか ─ Haskell から育った「圧縮代数」というメンタルモデル
naoya
16
3.6k
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
180
Android CLI
fornewid
0
170
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
420
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
190
What's New in Android 2026
veronikapj
0
180
言語を使う側から、作る側へ。 自作 Lisp で得た新たな気づき。
andpad
0
130
関数型プログラミングのメリットって何だろう?
wanko_it
0
190
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
0
120
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
190
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
170
Featured
See All Featured
The Mindset for Success: Future Career Progression
greggifford
PRO
0
430
The browser strikes back
jonoalderson
0
1.4k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
230
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.8k
So, you think you're a good person
axbom
PRO
2
2.1k
Writing Fast Ruby
sferik
630
63k
Un-Boring Meetings
codingconduct
0
350
Why Our Code Smells
bkeepers
PRO
340
58k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
520
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
390
Discover your Explorer Soul
emna__ayadi
2
1.2k
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