Advanced OOP and Design Patterns

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

3 comments

Comments 1 - 3 of 3 previous next Post a comment

  • + sarahhaim sarahhaim shl 1 month ago
    Images are very accurate to the topic.
  • + fjanis1979 fjanis1979 1 month ago
    Saw this presentation in Dallas. Very well done. The presentation and samples gave me an understanding that really helped. Meant to review on Joind.
  • + peterfriese Peter Friese 1 month ago
    Awesome preso. Though I’m not a PHP guy, I really enjolyed ho you motivate OOP and Design Patterns. Great stock images, BTW.
Post a comment
Embed Video
Edit your comment Cancel

24 Favorites & 1 Group

Advanced OOP and Design Patterns - Presentation Transcript

  1. Advanced OOP and Design Patterns Stefan Priebsch thePHP .cc CodeWorks 09 Copyright © 2009 thePHP.cc, Germany
  2. Premium PHP Consulting & Training. Worldwide. Sebastian Arne Stefan Bergmann Blankerts Priebsch
  3. Why OOP?
  4. <?php header('Content-Type: text/html; charset=' . $GLOBALS['charset']); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $lang_iso_code; ?>" PHP lang="<?php echo $lang_iso_code; ?>" dir="<?php echo $GLOBALS['text_dir']; ?>"> <head> <link rel="icon" href="./favicon.ico" type="image/x-icon" /> <title>phpMyAdmin <?php echo PMA_VERSION; ?> - <?php echo htmlspecialchars($HTTP_HOST); ?></title> <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $GLOBALS['charset']; ?>" /> <meta name="robots" content="noindex,nofollow" /> <script type="text/javascript"> window.onload = function() { if (onloadCnt == 0) { if (typeof(onLoadHandler) == "function") { onLoadHandler(); } };</script> <script src="./js/common.js" type="text/javascript"></script> SQL </head> <?php $query = "select `postId`,`filename`,`filesize`,`imgId` from `tiki_blog_posts_images` where `postId`=?"; $result = $this->query($query,array((int) $postId)); $ret = array(); while ($res = $result->fetchRow()) { $imgId = $res['imgId']; $res['link'] = "<img src='tiki-view_blog_post_image.php? imgId=$imgId' border='0' alt='image' />"; $parts = parse_url($_SERVER['REQUEST_URI']); $path = str_replace('tiki-blog_post.php', 'tiki- view_blog_post_image.php', $parts['path']); $res['absolute'] = $tikilib->httpPrefix(). $path . "? imgId=$imgId"; $ret[] = $res; } return $ret; } ?> <?php if ($GLOBALS['text_dir'] === 'ltr') { ?> <frame frameborder="0" id="frame_navigation" src="navigation.php<? php echo $url_query; ?>" name="frame_navigation" /><?php } ?> <frame frameborder="0" id="frame_content" src="<?php echo HTML $main_target; ?>" name="frame_content" /> <?php if ($GLOBALS['text_dir'] === 'rtl') { ?> <frame frameborder="0" id="frame_navigation" src="navigation.php<? php echo $url_query; ?>" name="frame_navigation" /><?php } ?> <noframes><body><p><?php echo $GLOBALS['strNoFrames']; ?></p> </body></noframes></frameset></html>
  5. <?php header('Content-Type: text/html; charset=' . $GLOBALS['charset']); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $lang_iso_code; ?>" PHP lang="<?php echo $lang_iso_code; ?>" dir="<?php echo $GLOBALS['text_dir']; ?>"> <head> <link rel="icon" href="./favicon.ico" type="image/x-icon" /> <title>phpMyAdmin <?php echo PMA_VERSION; ?> - <?php echo htmlspecialchars($HTTP_HOST); ?></title> <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $GLOBALS['charset']; ?>" /> <meta name="robots" content="noindex,nofollow" /> <script type="text/javascript"> window.onload = function() { if (onloadCnt == 0) { if (typeof(onLoadHandler) == "function") { onLoadHandler(); } };</script> <script src="./js/common.js" type="text/javascript"></script> SQL </head> <?php $query = "select `postId`,`filename`,`filesize`,`imgId` from `tiki_blog_posts_images` where `postId`=?"; $result = $this->query($query,array((int) $postId)); $ret = array(); while ($res = $result->fetchRow()) { $imgId = $res['imgId']; $res['link'] = "<img src='tiki-view_blog_post_image.php? imgId=$imgId' border='0' alt='image' />"; $parts = parse_url($_SERVER['REQUEST_URI']); $path = str_replace('tiki-blog_post.php', 'tiki- view_blog_post_image.php', $parts['path']); $res['absolute'] = $tikilib->httpPrefix(). $path . "? imgId=$imgId"; $ret[] = $res; } return $ret; } ?> <?php if ($GLOBALS['text_dir'] === 'ltr') { ?> <frame frameborder="0" id="frame_navigation" src="navigation.php<? php echo $url_query; ?>" name="frame_navigation" /><?php } ?> <frame frameborder="0" id="frame_content" src="<?php echo HTML $main_target; ?>" name="frame_content" /> <?php if ($GLOBALS['text_dir'] === 'rtl') { ?> <frame frameborder="0" id="frame_navigation" src="navigation.php<? php echo $url_query; ?>" name="frame_navigation" /><?php } ?> <noframes><body><p><?php echo $GLOBALS['strNoFrames']; ?></p> </body></noframes></frameset></html>
  6. <?php header('Content-Type: text/html; charset=' . $GLOBALS['charset']); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $lang_iso_code; ?>" PHP lang="<?php echo $lang_iso_code; ?>" dir="<?php echo $GLOBALS['text_dir']; ?>"> <head> <link rel="icon" href="./favicon.ico" type="image/x-icon" /> <title>phpMyAdmin <?php echo PMA_VERSION; ?> - <?php echo htmlspecialchars($HTTP_HOST); ?></title> <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $GLOBALS['charset']; ?>" /> <meta name="robots" content="noindex,nofollow" /> <script type="text/javascript"> window.onload = function() { if (onloadCnt == 0) { if (typeof(onLoadHandler) == "function") { onLoadHandler(); } };</script> <script src="./js/common.js" type="text/javascript"></script> SQL </head> <?php $query = "select `postId`,`filename`,`filesize`,`imgId` from `tiki_blog_posts_images` where `postId`=?"; $result = $this->query($query,array((int) $postId)); $ret = array(); while ($res = $result->fetchRow()) { $imgId = $res['imgId']; $res['link'] = "<img src='tiki-view_blog_post_image.php? imgId=$imgId' border='0' alt='image' />"; $parts = parse_url($_SERVER['REQUEST_URI']); $path = str_replace('tiki-blog_post.php', 'tiki- view_blog_post_image.php', $parts['path']); $res['absolute'] = $tikilib->httpPrefix(). $path . "? imgId=$imgId"; $ret[] = $res; } return $ret; } ?> <?php if ($GLOBALS['text_dir'] === 'ltr') { ?> <frame frameborder="0" id="frame_navigation" src="navigation.php<? php echo $url_query; ?>" name="frame_navigation" /><?php } ?> <frame frameborder="0" id="frame_content" src="<?php echo HTML $main_target; ?>" name="frame_content" /> <?php if ($GLOBALS['text_dir'] === 'rtl') { ?> <frame frameborder="0" id="frame_navigation" src="navigation.php<? php echo $url_query; ?>" name="frame_navigation" /><?php } ?> <noframes><body><p><?php echo $GLOBALS['strNoFrames']; ?></p> </body></noframes></frameset></html>
  7. PHP SQL HTML
  8. Presentation Logic Data Access
  9. Separation of Concerns
  10. Good OOP starts before classes come into play
  11. Do we need OOP?
  12. IF-GOTO programs
  13. LOOP programs
  14. WHILE programs
  15. IF-GOTO and WHILE programs are equally powerful.
  16. Every WHILE program can be simulated by a WHILE program with only one while loop.
  17. OOP is syntactical sugar
  18. Then Why OOP?
  19. Readability
  20. class BlogPosting { public function addComment(Comment $comment) }
  21. class BlogPosting { public function addComment(Comment $comment) { $this->comments[] = $comment; } }
  22. class BlogPosting { public function addComment(Comment $comment) { $this->comments[] = $comment; if ($comment->getAuthor()->isRegistered()) { $comment->setApproved(true); } } }
  23. Encapsulation
  24. Keeping Secrets
  25. Interface and Implementation
  26. $email->send(); $pdf->generate();
  27. Maintainability
  28. >150x Relative Cost of a Bugfix 50x 20x 10x 1x 5x Req Design Code DevT AccT Ops Source: Barry Boehm: „EQUITY Keynote Address“, March 19th, 2007
  29. Extensibility
  30. class Customer { protected $discount = 0; public function getDiscount() { return $this->discount; } }
  31. class PremiumCustomer extends Customer { protected $discount = 5; }
  32. class PremiumCustomer extends Customer { protected $discount = 5; public function getDiscount() { if ($this->signupYear < 2003) { return 10; } if ($this->getTotalRevenue() > 100000) { return 10; } return parent::getDiscount(); } }
  33. class PremiumCustomer extends Customer { protected $discount = 5; public function getDiscount() { if ($this->fulfilsYearCriterion() || $this->fulfilsRevenueCriterion()) { return 10; } return parent::getDiscount(); } ... }
  34. class PremiumCustomer extends Customer { ... protected function fulfilsYearCriterion() { return $this->signupYear < 2003; } protected function fulfilsRevenueCriterion() { return $this->getTotalRevenue() > 100000; } ... }
  35. class PremiumCustomer extends Customer { protected $specialDiscount= 10; public function getDiscount() { if ($this->fulfilsYearCriterion() || $this->fulfilsRevenueCriterion()) { return $this->specialDiscount; } return parent::getDiscount(); } }
  36. class MostValuedCustomer extends PremiumCustomer { protected $discount = 10; protected $specialDiscount= 20; }
  37. Reusability
  38. Only isolated and loosely coupled classes are reusable.
  39. Maintainability
  40. Is OOP slow?
  41. foo() 3.09 µsec Test::foo() 3.26 µsec $test->foo() 3.12 µsec $test = new Test(); $test->foo() 4.03 µsec Benchmark results are different on every system.
  42. 25% slower!
  43. 1 µsec
  44. print ~ 10 µsec file_get_contents() ~ 30 µsec mysql_connect() ~ 100 µsec HTTP GET Request ~ 35,000 µsec Benchmark results are different on every system.
  45. I/O is where the action is.
  46. OOP is fast enough.
  47. Dealing with Dependencies
  48. Decoupling
  49. Dependencies on Constants
  50. define('BASEPATH', '/some/absolute/path'); ... class Something { public function loadData() { $this->data = file_get_contents(BASEPATH . '/file.ext'); } } ... $something = new Something(); $something->loadData();
  51. class Something { protected $basePath = BASEPATH; public function loadData() { $this->data = file_get_contents($this->basePath . '/file.ext'); } }
  52. class Something { protected $basePath = BASEPATH; public function setBasePath($basePath) { $this->basePath = $basePath; } public function loadData() { $this->data = file_get_contents($this->basePath . '/file.ext'); } }
  53. $something = new Something(); $something->setBasePath(BASEPATH); $something->loadData();
  54. class Something { protected $basePath; public function setBasePath($basePath) { $this->basePath = $basePath; } public function loadData() { $this->data = file_get_contents($this->basePath . '/file.ext'); } }
  55. class Something { protected $basePath; public function setBasePath($basePath) { $this->basePath = $basePath; } public function loadData() { if (is_null($this->basePath)) { throw new RuntimeException('No basepath set'); } $this->data = file_get_contents($this->basePath . '/file.ext'); } }
  56. class Something { protected $basePath; public function __construct($basePath) { $this->basePath = $basePath; } public function loadData() { if (is_null($this->basePath)) { throw new RuntimeException('No basepath set'); } $this->data = file_get_contents($this->basePath . '/file.ext'); } }
  57. Files are also a dependency
  58. class Something { public function __construct($data) { $this->data = $data; } }
  59. Dependencies on Global Variables
  60. class Something { public function loadData() { global $dsn; … load data from database ... } }
  61. class Something { public function loadData($dsn) { … load data from database ... } }
  62. class Something { protected $dsn; public function __construct($dsn) { $this->dsn = $dsn; } public function loadData() { … load data from database ... } }
  63. class Something { protected $dbAdapter; public function __construct(DatabaseAdapter $dbAdapter) { $this->dbAdapter = $dbAdapter; } }
  64. Dependency Injection
  65. class Something { protected $dbAdapter; public function __construct(DatabaseAdapter $dbAdapter) { $this->dbAdapter = $dbAdapter; } public function loadData() { … ask somebody else to load data from database ... } }
  66. Delegation
  67. Let others do the work.
  68. class DatabaseAdapter { protected $dsn; public function __construct($dsn) { $this->dsn = $dsn; } }
  69. $dbAdapter = new DatabaseAdapter(); $something = new Something($dbAdapter); $something->doWork();
  70. class DummyDatabaseAdapter extends DatabaseAdapter { } $dbAdapter = new DummyDatabaseAdapter(); $something = new Something($dbAdapter); $something->doWork();
  71. class Something { protected $dbAdapter; public function __construct(DatabaseAdapter $dbAdapter = null) { if (is_null($dbAdapter)) { $dbAdapter = new DefaultDatabaseAdapter(); } $this->dbAdapter = $dbAdapter; } public function loadData() { … load data from database ... } }
  72. Dependencies on Functions
  73. class Something { public function doWork() { ... global_function(...); ... } }
  74. require_once 'global_function.php'; $something = new Something(); $something->doWork();
  75. require_once 'mock_global_function.php'; $something = new Something(); $something->doWork();
  76. Dependencies on Static Calls
  77. class Something { public function loadData() { $dsn = Configuration::getDsn(); … load data from database ... } }
  78. class Something { protected $configurationClass = 'Configuration'; public function setConfigurationClass($classname) { $this->configurationClass = $classname } public function loadData() { $classname = $this->configurationClass; $db = $classname::getDsn(); … load data from database ... } }
  79. ?
  80. class Something { protected $configurationClass = 'Configuration'; public function setConfigurationClass($classname) { $this->configurationClass = $classname } public function loadData() { $classname = $this->configurationClass; $db = $classname::getDsn(); … load data from database ... } }
  81. Will $classname actually be a class?
  82. class Something { protected $configurationClass = 'Configuration'; public function setConfigurationClass($classname) { $this->configurationClass = $classname } public function loadData() { $classname = $this->configurationClass; $db = $classname::getDsn(); … load data from database ... } }
  83. Will the class have a getDsn() method?
  84. Better let PHP enforce this.
  85. Dependencies on Objects
  86. class Something { public function doWork() { ... $this->log('…'); ... } }
  87. class Something { protected function log($message) { file_put_contents(LOGFILE, $message, FILE_APPEND); } public function doWork() { ... $this->log('…'); ... } }
  88. class Logger { public function log($message) { file_put_contents(LOGFILE, $message, FILE_APPEND); } }
  89. class Something { protected $logger; public function __construct() { $this->logger = new Logger(); } ... }
  90. class Something { protected $logger; public function __construct() { $this->logger = new Logger(); } public function doWork() { … $this->logger->log(...); ... } }
  91. class Something { protected $logger; public function __construct(Logger $logger) { $this->logger = $logger; } public function doWork() { … $this->logger->log(...); ... } }
  92. class Logger { public function log($message) { file_put_contents(LOGFILE, $message, FILE_APPEND); } }
  93. class Logger { protected $file; public function __construct($file) { $this->file = $file; } public function log($message) { ... file_put_contents($this->file, $message, FILE_APPEND); ... } }
  94. class DatabaseLogger extends Logger { protected $dsn; public function __construct($dsn) { $this->dsn = $dsn; } public function log($message) { … log $message to database $dsn ... } }
  95. class DbGateway { protected $dsn; public function __construct($dsn) { $this->dsn = $dsn; } ... }
  96. class DbGateway { protected $isConnected = false; ... protected function connect() { … connect to $dsn ... } public function query($query) { if (!$this->isConnected) { $this->connect(); } … run $query ... } ... }
  97. class DatabaseLogger extends Logger extends DbGateway { ... }
  98. Multiple Inheritance
  99. ?
  100. class Something { public function __construct(Logger $logger) { $this->logger = $logger; } public function doWork() { ... $this->logger->log(...); ... } }
  101. Do we really need to extend Logger?
  102. class FileLogger { protected $file; public function __construct($file) { $this->file = $file; } public function log($message) { ... file_put_contents($this->file, $message, FILE_APPEND); ... } }
  103. class DatabaseLogger extends DbGateway { public function log($message) { ... … write $message to database using $this->query() … ... } }
  104. class Something { public function __construct(Logger $logger) { $this->logger = $logger; } public function doWork() { ... $this->logger->log(...); ... } }
  105. How do we make the type hint work?
  106. Interfaces
  107. interface Loggable { public function log($message); }
  108. class FileLogger implements Loggable { protected $file; public function __construct($file) { $this->file = $file; } public function log($message) { ... file_put_contents($this->file, $message, FILE_APPEND); ... } }
  109. class DatabaseLogger extends DbGateway implements Loggable { public function log($message) { ... … write $message to database using $this->query() … ... } }
  110. class Something { public function __construct(Loggable $logger) { $this->logger = $logger; } protected function doWork() { ... $this->logger->log(...); ... } }
  111. $logger = new FileLogger('/path/to/logfile'); $something = new Something($logger); $something->doWork();
  112. $logger = new DatabaseLogger($dsn); $something = new Something($logger); $something->doWork();
  113. $logger = new DummyLogger(); $something = new Something($logger); $something->doWork();
  114. class DummyLogger implements Loggable { public function log($message) { } }
  115. Interfaces make good type hints.
  116. Abstract Classes and Methods
  117. class Something { public function run() { // initialize … // perform calculations … // write log entry … // sort output ... } }
  118. class Something { public function run() { $this->initialize(); $this->calculateStuff(); $this->doLogging(); $this->sortOutput(); } }
  119. Template Method
  120. class Something { abstract protected function initialize(); abstract protected function calculateStuff(); abstract protected function doLogging(); abstract protected function sortOutput(); public function run() { $this->initialize(); $this->calculateStuff(); $this->doLogging(); $this->sortOutput(); } }
  121. abstract class Something { abstract protected function initialize(); abstract protected function calculateStuff(); abstract protected function doLogging(); abstract protected function sortOutput(); public function run() { $this->initialize(); $this->calculateStuff(); $this->doLogging(); $this->sortOutput(); } }
  122. abstract class Something { abstract protected function initialize(); abstract protected function calculateStuff(); abstract protected function doLogging(); abstract protected function sortOutput(); final public function run() { $this->initialize(); $this->calculateStuff(); $this->doLogging(); $this->sortOutput(); } }
  123. class ConcreteSomething extends Something { protected function initialize() { } protected function calculateStuff() { } protected function doLogging() { } protected function sortOutput() { } }
  124. Abstract classes cannot be instantiated.
  125. „Every pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.“ -- Christopher Alexander
  126. A design pattern is a general reusable solution to a commonly occurring problem.
  127. A design pattern is not a finished design that can be transformed directly into code.
  128. Architectural Patterns Design Patterns Idioms
  129. Problem: display a progress bar
  130. class Something { protected function performCalculation() { ... foreach ($items as $item) { … process the item … print '.'; } ... } }
  131. Subject/Observer
  132. The subject maintains a list of observers and notifies them on status changes.
  133. interface SplSubject { public function attach(SplObserver $observer); public function detach(SplObserver $observer); public function notify(); }
  134. interface SplObserver { public function update(SplSubject $subject); }
  135. class Subject implements SplSubject { protected $observers; public function __construct() { $this->observers = new SplObjectStorage(); } ... }
  136. class Subject implements SplSubject { … public function attach(SplObserver $observer) { $observers->attach($observer); } public function detach(SplObserver $observer) { $observers->detach($observer); } ... }
  137. class Subject implements SplSubject { ... public function notify() { foreach ($this->observers as $observer) { $observer->update($this); } } }
  138. class Something extends Subject implements SplSubject { public function doWork() { … foreach ($items as $item) { … $this->notify(); } ... } }
  139. class ProgressBar implements SplObserver { public function update(SplSubject $subject) { print '. '; } }
  140. class Something extends Subject implements SplSubject { public function doWork() { … foreach ($items as $item) { $this->currentItem = $item; … $this->notify(); } ... } public function getCurrentItem() { return $this->currentItem() } }
  141. class ProgressBar implements SplObserver { public function update(SplSubject $subject) { $item = $subject->getCurrentItem(); … } }
  142. class ProgressBar implements SplObserver { public function update(SplSubject $subject) { $item = $subject->getCurrentItem(); if ($item->isDir()) { print '[' . $item->getPathname() . '] '; } if ($item->isFile()) { print '.'; } } }
  143. $progressBar = new ProgressBar(); $something = new Something(); $something->attach($progressBar); $something->doWork();
  144. Factory
  145. Defines an interface for creating a family of objects. The concrete classes that are to be instantiated are not clearly defined.
  146. Creates objects for you.
  147. abstract class Plane { static public function getInstance($type) { return new $type; } }
  148. class Boeing extends Plane { } class Airbus extends Plane { } class Boeing777 extends Boeing { } class AirbusA340 extends Airbus { }
  149. $a = Plane::getInstance('Boeing777'); $b = Plane::getInstance('AirbusA340');
  150. abstract class Plane { static public function getInstance($type) { switch ($type) { case 'Boeing777': return new Boeing777(); … default: throw new RuntimeException('...'); } } }
  151. abstract class Plane { static public function getInstance($type) { if (!in_array($type, array('Boeing777', 'AirbusA340', …))) { throw new RuntimeException('...'); } return new $type; } }
  152. abstract class Plane { static public function getInstance($type) { if (!class_exists($type)) { throw new RuntimeException('...'); } return new $type; } }
  153. abstract class Plane { protected $classMap = array( '777' => 'Boeing777', ... ); static public function getInstance($type) { if (!isset($this->classMap[$type])) { throw new RuntimeException('...'); } $classname = $this->classMap[$type]; return new $classname; } }
  154. Singleton
  155. Limits number of instances of a class to one object.
  156. Limits number of instances of a class to one object.
  157. class Singleton { static protected $instance; static public function getInstance() { if (is_null(self::$instance)) { self::$instance = new Singleton(); } return self::$instance; } }
  158. class Singleton { static protected $instance; private function __construct() {} private function __clone() {} static public function getInstance() { if (is_null(self::$instance)) { self::$instance = new Singleton(); } return self::$instance; } }
  159. class Something { public function doWork() { $singleton = Singleton::getInstance(); $singleton->... ... } }
  160. class Something { public function doWork($reference) { $reference->... ... } }
  161. Registry
  162. A well-known object used by others to find shared objects and services.
  163. … $db = StaticRegistry::getDbAdapter(); ...
  164. class StaticRegistry { static protected $dbAdapter; static public function getDbAdapter() { if (is_null(self::$dbAdapter)) { self::$dbAdapter = new DbAdapter(); } return self::$dbAdapter; } }
  165. … $db = Registry::getInstance()->getDbAdapter(); ...
  166. class SingletonRegistry { static protected $instance; protected $dbAdapter; static public function getInstance() { … } public function getDbAdapter() { if (is_null($this->dbAdapter)) { $this->dbAdapter = new DbAdapter(); } return $this->dbAdapter; } }
  167. class Registry { … protected $dbAdapterClass = 'DbAdapter'; protected $dbAdapter; public function setDbAdapterClass($class) { $this->dbAdapterClass = $class; } public function getDbAdapter() { if (is_null($this->dbAdapter)) { $classname = $this->dbAdapterClass; $this->dbAdapter = new $classname; } return $this->dbAdapter; } }
  168. MVC
  169. Classical MVC
  170. Model
  171. Represents domain-specific data
  172. View
  173. Renders model data
  174. Controller
  175. Handles events and modifies model
  176. Presentation V Logic C Data Access M
  177. Model != Data Access
  178. Model != Data Access
  179. Controller View Model
  180. Controller observes View Controller View Model
  181. Controller fetches data from View Controller View Model
  182. Controller modifies Model Controller View Model
  183. View observes Model Controller View Model
  184. View fetches data from Model Controller View Model
  185. MVC on the Web
  186. Client V HTTP Request HTTP Response Server C M
  187. View is remote
  188. Controller View Model
  189. Controller can't observe View Controller View Model
  190. View can't observe Model Controller View Model
  191. View doesn't talk to Controller Front Controller Controller View Model
  192. Front Controller Controller HTTP Request View Model
  193. Front execute() Controller Controller HTTP Request View Model
  194. Front execute() Controller Controller HTTP Request View Model getData()
  195. Front execute() Controller Controller HTTP ) ata( Request D set View Model getData()
  196. Controller selects View
  197. View generates full HTML page
  198. Workflows by Controller chaining
  199. Lean Controller, Fat Model
  200. No data access in Controller or Model
  201. No presentation in Controller or Model
  202. Separation of Concerns
  203. Golden Rules
  204. „Hang the rules. They're more like guidelines anyway.“ --Elizabeth Swann, Pirates of the Caribbean
  205. Make dependencies explicit.
  206. „Life can only be understood backwards, backwards, but it must be lived forwards.“ forwards.“ -- Soren Kierkegaard
  207. Solve your problem.
  208. Do one thing at a time.
  209. Let others do the work.
  210. Do not care about others.
  211. Keep it simple.
  212. „Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.“ -- Brian W. Kernighan
  213. Do not comment.
  214. Do not comment. * * Some restrictions apply.
  215. ”The most important single aspect of software development ... … is to be clear about what you are trying to build.” -- Bjarne Stroustrup
  216. Name the thing.
  217. „There's no sense being exact about something if you don't even know what you're talking about.“ -- John von Neumann
  218. It has to fit on one page.
  219. ”Measuring programming progress by lines of code is like measuring aircraft building progress by weight.” weight.” -- Bill Gates
  220. Accept Change.
  221. ”I may not have gone where I intended to go, but I think I have ended up where I needed to be.“ -- Douglas Adams
  222. Thank you. Please rate me: http://joind.in
  223. Contact ■ http://thePHP.cc ■ http://www.priebsch.de ■ http://www.slideshare.net/spriebsch ■ http://twitter.com/spriebsch ■ stefan@thePHP.cc, IRC: spriebsch Copyright © 2009 thePHP.cc, Germany

+ Stefan PriebschStefan Priebsch, 1 month ago

custom

2923 views, 24 favs, 2 embeds more stats

There is nothing wrong with procedural programming more

More info about this document

© All Rights Reserved

Go to text version

  • Total Views 2923
    • 2406 on SlideShare
    • 517 from embeds
  • Comments 3
  • Favorites 24
  • Downloads 185
Most viewed embeds
  • 508 views on http://www.priebsch.de
  • 9 views on http://www.php.rk.edu.pl

more

All embeds
  • 508 views on http://www.priebsch.de
  • 9 views on http://www.php.rk.edu.pl

less

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

Cancel
File a copyright complaint
Having problems? Go to our helpdesk?

Categories

Groups / Events