$30 off During Our Annual Pro Sale. View Details »
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Object-georienteerd Programmeren
Search
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
10
PHP Kitchen Nightmares (PHP.FRL)
skoop
0
58
Sustainable open source contributions in your business (CakeFest 2024)
skoop
0
91
Domain-Driven Design: The Basics (SymfonyCon 2023, Brussels)
skoop
0
210
Domain-Driven Design: The Basics (Cakefest)
skoop
0
220
PHP Kitchen Nightmares
skoop
0
59
Domain Driven Design - The Basics (TechTuesday XXL, Tilburg)
skoop
0
97
7 Lessons You Can Learn From Disney Movies (SymfonyCon 2022)
skoop
0
280
Mental Health in the Workplace (SymfonyCon 2019, Amsterdam)
skoop
0
700
Other Decks in Programming
See All in Programming
NUMA環境とコンテナランタイム ― youki における Linux Memory Policy 実装
n4mlz
1
110
dotfiles 式年遷宮 令和最新版
masawada
1
680
Microservices Platforms: When Team Topologies Meets Microservices Patterns
cer
PRO
1
930
開発に寄りそう自動テストの実現
goyoki
1
510
バックエンドエンジニアによる Amebaブログ K8s 基盤への CronJobの導入・運用経験
sunabig
0
140
Querying Design System デザインシステムの意思決定を支える構造検索
ikumatadokoro
1
1.3k
令和最新版Android Studioで化石デバイス向けアプリを作る
arkw
0
260
[堅牢.py #1] テストを書かない研究者に送る、最初にテストを書く実験コード入門 / Let's start your ML project by writing tests
shunk031
12
7k
AIエージェントを活かすPM術 AI駆動開発の現場から
gyuta
0
240
CSC509 Lecture 14
javiergs
PRO
0
220
モダンJSフレームワークのビルドプロセス 〜なぜReactは503行、Svelteは12行なのか〜
fuuki12
0
200
dnx で実行できるコマンド、作ってみました
tomohisa
0
140
Featured
See All Featured
What's in a price? How to price your products and services
michaelherold
246
12k
Testing 201, or: Great Expectations
jmmastey
46
7.8k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
1.8k
Designing Experiences People Love
moore
142
24k
Raft: Consensus for Rubyists
vanstee
140
7.2k
GraphQLの誤解/rethinking-graphql
sonatard
73
11k
Reflections from 52 weeks, 52 projects
jeffersonlam
355
21k
Learning to Love Humans: Emotional Interface Design
aarron
274
41k
Into the Great Unknown - MozCon
thekraken
40
2.2k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.7k
Large-scale JavaScript Application Architecture
addyosmani
514
110k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
132
19k
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