Object-georienteerd Programmeren

Object-georienteerd Programmeren

The slides for the OO-training during the Techademy trainingday on June 27th

A8f72e32766355f12a56ede9aaa0ee78?s=128

Stefan Koopmanschap

June 27, 2014
Tweet

Transcript

  1. Object'georienteerd.programmeren Techademy,*27-06-2014

  2. De#onderwerpen

  3. De#onderwerpen • Wat%is%OO?

  4. De#onderwerpen • Wat%is%OO? • De%basistermen

  5. De#onderwerpen • Wat%is%OO? • De%basistermen • SOLID

  6. De#onderwerpen • Wat%is%OO? • De%basistermen • SOLID • Zelf%refactoren

  7. De#onderwerpen • Wat%is%OO? • De%basistermen • SOLID • Zelf%refactoren •

    Hoe%nu%verder?
  8. Een$stukje$geschiedenis

  9. Een$stukje$geschiedenis • Eind&jaren&'50,&begin&jaren&'60&bij&MIT

  10. Een$stukje$geschiedenis • Eind&jaren&'50,&begin&jaren&'60&bij&MIT • Oude&versies&van&PHP&hadden&niet&echt&een&object&model

  11. 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

  12. Wat$is$OO?

  13. Wat$is$OO? • De$tegenhanger$van$"Procedureel/Func5onal$Programming"

  14. Wat$is$OO? • De$tegenhanger$van$"Procedureel/Func5onal$Programming" • Je$werkt$met$objecten

  15. Wat$is$OO? • De$tegenhanger$van$"Procedureel/Func5onal$Programming" • Je$werkt$met$objecten • Abstrac5e$van$func5onaliteit$en$data

  16. 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>";
  17. Wat$is$OO?

  18. Wat$is$OO? • Configura*e,in,je,code

  19. Wat$is$OO? • Configura*e,in,je,code • Database,logica

  20. Wat$is$OO? • Configura*e,in,je,code • Database,logica • Request/inputa:andeling,

  21. Wat$is$OO? • Configura*e,in,je,code • Database,logica • Request/inputa:andeling • Weergavelogica

  22. 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);
  23. De#basistermen Laten&we&beginnen&bij&het&begin

  24. Class <?php class Db { }

  25. Object <?php $db = new Db();

  26. Func%on <?php function doSomething() { }

  27. Method <?php class Db { public function query() { }

    }
  28. Magic&Methods <?php class User { public function __toString() { return

    $this->getName(); } }
  29. Magic&Methods • __construct() • __destruct() • __call() • __callSta1c() •

    __get() • __set() • __isset()
  30. Magic&Methods • __unset() • __sleep() • __wakeup() • __toString() •

    __invoke() • _setstate() • __clone()
  31. Constructor <?php class Db { public function __construct($host, $user, $pass,

    $name) { $this->connection = mysql_connect($host, $user, $pass); mysql_select_db($name, $this->connection); } }
  32. Sta$c <?php class Foo { static public function bar() {

    return 'no instance'; } } echo Foo::bar(); // echo's "no instance"
  33. Variable <?php $foo = 'bar';

  34. Property <?php class Db { private $connection; public function __construct()

    { // etc } }
  35. 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); } }
  36. Abstrac(e Het$lostrekken$van$logica$naar$aparte$stukken$code Eigenlijk)precies)wat)ik)je)net)heb)laten)zien

  37. 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); } }
  38. 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 }
  39. 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);
  40. 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 }
  41. 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 }
  42. Type%hin)ng Vertel&wat&voor&soort&parameter&je&verwacht <?php class BarRepository { public function __construct(Db $db)

    { // etc } }
  43. Type%hin)ng <?php class BarRepository { public function __construct(DbInterface $db) {

    // etc } }
  44. SOLID • Single'Responsibility'Principle

  45. Single'Responsibility'Principle • Iedere&class&hee,&maar&één&enkele&verantwoordelijkheid

  46. Single'Responsibility'Principle • Iedere&class&hee,&maar&één&enkele&verantwoordelijkheid • Alle&implementa9elogica&voor&deze&verantwoordelijk&is& geencapsuleerd

  47. 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

  48. SOLID • Single'Responsibility'Principle • Open/Closed'Principle

  49. Open/Closed+Principle • Iedere&class&moet&open&staan&voor&uitbreiding,&maar&gesloten& voor&aanpassing

  50. 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

  51. 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

  52. 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
  53. 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
  54. SOLID • Single'Responsibility'Principle • Open/Closed'Principle • Liskov'Subs9tu9on'Principle

  55. Liskov'Subs+tu+on'Principle • Classes'die'overerven'van'een'basisclass'moeten'die'basisclass' kunnen'vervangen

  56. 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'

  57. 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
  58. SOLID • Single'Responsibility'Principle • Open/Closed'Principle • Liskov'Subs9tu9on'Principle • Interface'Segrega9on'Principle

  59. Interface)Segrega,on)Principle Een$specifieke$func-onaliteit$hoort$alleen$maar$kennis$te$hebben$ van$methodes$voor$die$func-onaliteit

  60. 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

  61. 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

  62. SOLID • Single'Responsibility'Principle • Open/Closed'Principle • Liskov'Subs9tu9on'Principle • Interface'Segrega9on'Principle •

    Dependency'Inversion'Principle
  63. Dependency(Inversion(Principle Een$module$dient$geen$harde$a0ankelijkheden$te$hebben$van$ andere$modules

  64. Dependency(Inversion(Principle Een$module$dient$geen$harde$a0ankelijkheden$te$hebben$van$ andere$modules • In$PHP$vooral$populair$via$Dependency$Injec5on

  65. 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

  66. 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

  67. 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
  68. Excep&ons

  69. Excep&ons • Een%speciaal%soort%object

  70. Excep&ons • Een%speciaal%soort%object • Als%er%iets%mis%gaat%kan%deze%worden%"gegooid"

  71. Excep&ons • Een%speciaal%soort%object • Als%er%iets%mis%gaat%kan%deze%worden%"gegooid" • Dit%kan%hogerop%in%de%code%worden%"opgevangen"

  72. 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

  73. Excep&ons <?php class Db { public function connect($host, $user, $pass)

    { if ($user == '') { throw new InvalidArgumentException('Username may not be empty'); } } }
  74. 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 }
  75. Namespaces

  76. Namespaces • Zorgen(voor(extra(structuur(in(de(code

  77. Namespaces • Zorgen(voor(extra(structuur(in(de(code • Zorgt(ervoor(dat(je(meerdere(classes(met(dezelfde(naam(kan( hebben

  78. Namespaces • Zorgen(voor(extra(structuur(in(de(code • Zorgt(ervoor(dat(je(meerdere(classes(met(dezelfde(naam(kan( hebben • Vroeger:(ZendSearchLuceneSearchQuery_Term

  79. 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

  80. 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
  81. Namespaces <?php namespace Database; class BaseDb { // etc }

  82. Namespaces <?php namespace Database\Driver; use Database\BaseDb as Db; class Mysql

    extends Db { // etc }
  83. Namespaces h"p:/ /www.php(fig.org/psr/psr(0/

  84. 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
  85. Hoe$nu$verder? • Best&prac+ces:&Gebruik&design&pa5erns

  86. Hoe$nu$verder? • Best&prac+ces:&Gebruik&design&pa5erns • Refactor&je&eigen&code

  87. Hoe$nu$verder? • Best&prac+ces:&Gebruik&design&pa5erns • Refactor&je&eigen&code • Lezen!&Er&zijn&veel&boeken&over&dit&onderwerp

  88. 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

  89. 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
  90. Feedback h"ps:/ /joind.in/11407