advanced oop and design patterns
DESCRIPTION
Stefan Priebsch's slides from Codeworks 2009TRANSCRIPT
![Page 1: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/1.jpg)
Copyright © 2009 thePHP.cc, Germany
Advanced OOPand Design Patterns
Stefan PriebschthePHP.cc
CodeWorks 09
![Page 2: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/2.jpg)
Premium PHP Consulting & Training. Worldwide.
ArneBlankerts
Sebastian Bergmann
StefanPriebsch
![Page 3: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/3.jpg)
WhyWhy OOP?OOP?
![Page 4: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/4.jpg)
<?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; ?>" 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></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 $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>
PHPPHP
HTMLHTML
SQLSQL
![Page 5: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/5.jpg)
<?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; ?>" 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></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 $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>
PHPPHP
HTMLHTML
SQLSQL
![Page 6: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/6.jpg)
<?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; ?>" 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></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 $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>
PHPPHP
HTMLHTML
SQLSQL
![Page 7: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/7.jpg)
PHPPHP
HTMLHTML
SQLSQL
![Page 8: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/8.jpg)
PresentationPresentation
LogicLogic
Data AccessData Access
![Page 9: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/9.jpg)
Separation ofSeparation ofConcernsConcerns
![Page 10: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/10.jpg)
Good OOP starts Good OOP starts before classesbefore classescome into playcome into play
![Page 11: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/11.jpg)
Do weDo weneed OOP?need OOP?
![Page 12: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/12.jpg)
IF-GOTO programsIF-GOTO programs
![Page 13: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/13.jpg)
LOOP programsLOOP programs
![Page 14: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/14.jpg)
WHILE programsWHILE programs
![Page 15: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/15.jpg)
IF-GOTO andIF-GOTO andWHILE programsWHILE programsare equally powerful.are equally powerful.
![Page 16: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/16.jpg)
Every WHILE programEvery WHILE programcan be simulated by acan be simulated by aWHILE program withWHILE program withonly one while loop.only one while loop.
![Page 17: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/17.jpg)
OOP isOOP issyntactical sugarsyntactical sugar
![Page 18: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/18.jpg)
Then Why OOP?Then Why OOP?
![Page 19: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/19.jpg)
ReadabilityReadability
![Page 20: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/20.jpg)
class BlogPosting{ public function addComment(Comment $comment)}
![Page 21: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/21.jpg)
class BlogPosting{ public function addComment(Comment $comment) { $this->comments[] = $comment; }}
![Page 22: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/22.jpg)
class BlogPosting{ public function addComment(Comment $comment) { $this->comments[] = $comment;
if ($comment->getAuthor()->isRegistered()) { $comment->setApproved(true); } }}
![Page 23: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/23.jpg)
EncapsulationEncapsulation
![Page 24: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/24.jpg)
Keeping SecretsKeeping Secrets
![Page 25: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/25.jpg)
InterfaceInterfaceand and
ImplementationImplementation
![Page 26: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/26.jpg)
$email->send();$email->send();
$pdf->generate();$pdf->generate();
![Page 27: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/27.jpg)
MaintainabilityMaintainability
![Page 28: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/28.jpg)
Source: Barry Boehm: „EQUITY Keynote Address“, March 19th, 2007Source: Barry Boehm: „EQUITY Keynote Address“, March 19th, 2007
DesignDesign CodeCodeReqReq DevTDevT OpsOps
Rela
tive C
ost
of
a B
ug
fix
Rela
tive C
ost
of
a B
ug
fix
1x1x 5x5x10x10x
20x20x
50x50x
AccTAccT
>150x>150x
![Page 29: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/29.jpg)
ExtensibilityExtensibility
![Page 30: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/30.jpg)
class Customer{ protected $discount = 0;
public function getDiscount() { return $this->discount; }}
![Page 31: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/31.jpg)
class PremiumCustomer extends Customer{ protected $discount = 5;}
![Page 32: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/32.jpg)
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(); }}
![Page 33: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/33.jpg)
class PremiumCustomer extends Customer{ protected $discount = 5;
public function getDiscount() { if ($this->fulfilsYearCriterion() || $this->fulfilsRevenueCriterion()) {
return 10; }
return parent::getDiscount(); }
...}
![Page 34: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/34.jpg)
class PremiumCustomer extends Customer{ ...
protected function fulfilsYearCriterion() { return $this->signupYear < 2003; }
protected function fulfilsRevenueCriterion() { return $this->getTotalRevenue() > 100000; }
...}
![Page 35: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/35.jpg)
class PremiumCustomer extends Customer{ protected $specialDiscount= 10;
public function getDiscount() { if ($this->fulfilsYearCriterion() || $this->fulfilsRevenueCriterion()) {
return $this->specialDiscount; }
return parent::getDiscount(); }}
![Page 36: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/36.jpg)
class MostValuedCustomer extends PremiumCustomer{ protected $discount = 10; protected $specialDiscount= 20;}
![Page 37: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/37.jpg)
ReusabilityReusability
![Page 38: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/38.jpg)
Only isolated andOnly isolated andloosely coupledloosely coupled
classes are reusable.classes are reusable.
![Page 39: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/39.jpg)
MaintainabilityMaintainability
![Page 40: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/40.jpg)
Is OOP slow?Is OOP slow?
![Page 41: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/41.jpg)
Benchmark results are different on every system.Benchmark results are different on every system.
foo() foo() 3.09 µsec3.09 µsec
Test::foo() 3.26 µsec
$test->foo() 3.12 µsec
$test = new Test();$test->foo() 4.03 µsec
![Page 42: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/42.jpg)
25% slower!25% slower!
![Page 43: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/43.jpg)
1 µsec1 µsec
![Page 44: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/44.jpg)
Benchmark results are different on every system.Benchmark results are different on every system.
print ~ 10 µsec
file_get_contents() ~ 30 µsec
mysql_connect() ~ 100 µsec
HTTP GET Request ~ 35,000 µsec
![Page 45: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/45.jpg)
I/O is whereI/O is wherethe action is.the action is.
![Page 46: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/46.jpg)
OOP is fast OOP is fast enough.enough.
![Page 47: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/47.jpg)
Dealing with Dealing with DependenciesDependencies
![Page 48: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/48.jpg)
DecouplingDecoupling
![Page 49: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/49.jpg)
DependenciesDependencieson Constantson Constants
![Page 50: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/50.jpg)
define('BASEPATH', '/some/absolute/path');...
class Something{ public function loadData() { $this->data = file_get_contents(BASEPATH . '/file.ext'); }}
...$something = new Something();$something->loadData();
![Page 51: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/51.jpg)
class Something{ protected $basePath = BASEPATH; public function loadData() { $this->data = file_get_contents($this->basePath . '/file.ext'); }}
![Page 52: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/52.jpg)
class Something{ protected $basePath = BASEPATH; public function setBasePath($basePath) { $this->basePath = $basePath; }
public function loadData() { $this->data = file_get_contents($this->basePath . '/file.ext'); }}
![Page 53: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/53.jpg)
$something = new Something();$something->setBasePath(BASEPATH);$something->loadData();
![Page 54: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/54.jpg)
class Something{ protected $basePath; public function setBasePath($basePath) { $this->basePath = $basePath; }
public function loadData() { $this->data = file_get_contents($this->basePath . '/file.ext'); }}
![Page 55: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/55.jpg)
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'); }}
![Page 56: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/56.jpg)
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'); }}
![Page 57: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/57.jpg)
Files are also a Files are also a dependencydependency
![Page 58: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/58.jpg)
class Something{ public function __construct($data) { $this->data = $data; }}
![Page 59: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/59.jpg)
Dependencies on Dependencies on Global VariablesGlobal Variables
![Page 60: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/60.jpg)
class Something{ public function loadData() { global $dsn;
… load data from database ... }}
![Page 61: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/61.jpg)
class Something{ public function loadData($dsn) { … load data from database ... }}
![Page 62: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/62.jpg)
class Something{ protected $dsn;
public function __construct($dsn) { $this->dsn = $dsn; }
public function loadData() { … load data from database ... }}
![Page 63: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/63.jpg)
class Something{ protected $dbAdapter;
public function __construct(DatabaseAdapter $dbAdapter) { $this->dbAdapter = $dbAdapter; }}
![Page 64: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/64.jpg)
Dependency Dependency InjectionInjection
![Page 65: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/65.jpg)
class Something{ protected $dbAdapter;
public function __construct(DatabaseAdapter $dbAdapter) { $this->dbAdapter = $dbAdapter; }
public function loadData() { … ask somebody else to load data from database ... }}
![Page 66: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/66.jpg)
DelegationDelegation
![Page 67: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/67.jpg)
Let othersLet othersdo the work.do the work.
![Page 68: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/68.jpg)
class DatabaseAdapter{ protected $dsn;
public function __construct($dsn) { $this->dsn = $dsn; }}
![Page 69: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/69.jpg)
$dbAdapter = new DatabaseAdapter();
$something = new Something($dbAdapter);$something->doWork();
![Page 70: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/70.jpg)
class DummyDatabaseAdapter extends DatabaseAdapter{}
$dbAdapter = new DummyDatabaseAdapter();
$something = new Something($dbAdapter);$something->doWork();
![Page 71: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/71.jpg)
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 ... }}
![Page 72: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/72.jpg)
DependenciesDependencieson Functionson Functions
![Page 73: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/73.jpg)
class Something{ public function doWork() { ... global_function(...); ... }}
![Page 74: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/74.jpg)
require_once 'global_function.php';
$something = new Something();$something->doWork();
![Page 75: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/75.jpg)
require_once 'mock_global_function.php';
$something = new Something();$something->doWork();
![Page 76: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/76.jpg)
DependenciesDependencieson Static Callson Static Calls
![Page 77: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/77.jpg)
class Something{ public function loadData() { $dsn = Configuration::getDsn();
… load data from database ... }}
![Page 78: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/78.jpg)
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 ... }}
![Page 79: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/79.jpg)
??
![Page 80: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/80.jpg)
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 ... }}
![Page 81: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/81.jpg)
Will $classnameWill $classnameactually be a class?actually be a class?
![Page 82: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/82.jpg)
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 ... }}
![Page 83: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/83.jpg)
Will the class haveWill the class havea getDsn() method?a getDsn() method?
![Page 84: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/84.jpg)
Better let PHP Better let PHP enforce this.enforce this.
![Page 85: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/85.jpg)
DependenciesDependencieson Objectson Objects
![Page 86: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/86.jpg)
class Something{ public function doWork() { ... $this->log('…'); ... }}
![Page 87: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/87.jpg)
class Something{ protected function log($message) { file_put_contents(LOGFILE, $message, FILE_APPEND); }
public function doWork() { ... $this->log('…'); ... }}
![Page 88: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/88.jpg)
class Logger{ public function log($message) { file_put_contents(LOGFILE, $message, FILE_APPEND); }}
![Page 89: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/89.jpg)
class Something{ protected $logger;
public function __construct() { $this->logger = new Logger(); }
...}
![Page 90: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/90.jpg)
class Something{ protected $logger;
public function __construct() { $this->logger = new Logger(); }
public function doWork() { … $this->logger->log(...); ... }}
![Page 91: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/91.jpg)
class Something{ protected $logger;
public function __construct(Logger $logger) { $this->logger = $logger; }
public function doWork() { … $this->logger->log(...); ... }}
![Page 92: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/92.jpg)
class Logger{ public function log($message) { file_put_contents(LOGFILE, $message, FILE_APPEND); }}
![Page 93: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/93.jpg)
class Logger{ protected $file;
public function __construct($file) { $this->file = $file; }
public function log($message) { ... file_put_contents($this->file, $message, FILE_APPEND); ... }}
![Page 94: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/94.jpg)
class DatabaseLogger extends Logger{ protected $dsn;
public function __construct($dsn) { $this->dsn = $dsn; }
public function log($message) { … log $message to database $dsn ... }}
![Page 95: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/95.jpg)
class DbGateway{ protected $dsn;
public function __construct($dsn) { $this->dsn = $dsn; }
...}
![Page 96: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/96.jpg)
class DbGateway{ protected $isConnected = false;
...
protected function connect() { … connect to $dsn ... }
public function query($query) { if (!$this->isConnected) { $this->connect(); }
… run $query ... }
...}
![Page 97: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/97.jpg)
class DatabaseLogger extends Logger extends DbGateway{ ...}
![Page 98: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/98.jpg)
Multiple Inheritance
![Page 99: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/99.jpg)
??
![Page 100: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/100.jpg)
class Something{ public function __construct(Logger $logger) { $this->logger = $logger; }
public function doWork() { ... $this->logger->log(...); ... }}
![Page 101: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/101.jpg)
Do we really need to Do we really need to extend Logger?extend Logger?
![Page 102: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/102.jpg)
class FileLogger{ protected $file;
public function __construct($file) { $this->file = $file; }
public function log($message) { ... file_put_contents($this->file, $message, FILE_APPEND); ... }}
![Page 103: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/103.jpg)
class DatabaseLogger extends DbGateway{ public function log($message) { ... … write $message to database using $this->query() … ... }}
![Page 104: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/104.jpg)
class Something{ public function __construct(Logger $logger) { $this->logger = $logger; }
public function doWork() { ... $this->logger->log(...); ... }}
![Page 105: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/105.jpg)
How do we makeHow do we makethe type hint work?the type hint work?
![Page 106: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/106.jpg)
InterfacesInterfaces
![Page 107: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/107.jpg)
interface Loggable{ public function log($message);}
![Page 108: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/108.jpg)
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); ... }}
![Page 109: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/109.jpg)
class DatabaseLogger extends DbGateway implements Loggable{ public function log($message) { ... … write $message to database using $this->query() … ... }}
![Page 110: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/110.jpg)
class Something{ public function __construct(Loggable $logger) { $this->logger = $logger; }
protected function doWork() { ... $this->logger->log(...); ... }}
![Page 111: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/111.jpg)
$logger = new FileLogger('/path/to/logfile');
$something = new Something($logger);$something->doWork();
![Page 112: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/112.jpg)
$logger = new DatabaseLogger($dsn);
$something = new Something($logger);$something->doWork();
![Page 113: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/113.jpg)
$logger = new DummyLogger();
$something = new Something($logger);$something->doWork();
![Page 114: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/114.jpg)
class DummyLogger implements Loggable{ public function log($message) { }}
![Page 115: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/115.jpg)
Interfaces makeInterfaces makegood type hints.good type hints.
![Page 116: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/116.jpg)
Abstract Classes Abstract Classes and Methodsand Methods
![Page 117: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/117.jpg)
class Something{ public function run() { // initialize …
// perform calculations …
// write log entry …
// sort output ... }}
![Page 118: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/118.jpg)
class Something{ public function run() { $this->initialize(); $this->calculateStuff(); $this->doLogging(); $this->sortOutput(); }}
![Page 119: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/119.jpg)
Template MethodTemplate Method
![Page 120: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/120.jpg)
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(); }}
![Page 121: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/121.jpg)
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(); }}
![Page 122: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/122.jpg)
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(); }}
![Page 123: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/123.jpg)
class ConcreteSomething extends Something{ protected function initialize() { }
protected function calculateStuff() { }
protected function doLogging() { }
protected function sortOutput() { }}
![Page 124: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/124.jpg)
Abstract classes Abstract classes cannot be instantiated.cannot be instantiated.
![Page 125: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/125.jpg)
![Page 126: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/126.jpg)
![Page 127: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/127.jpg)
![Page 128: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/128.jpg)
„„Every pattern describes a problemEvery pattern describes a problemwhich occurs over and over again inwhich occurs over and over again in
our environment, and then describes our environment, and then describesthe core of the solution to that problem,the core of the solution to that problem,
in such a way that you can use thisin such a way that you can use thissolution a million times over, withoutsolution a million times over, withoutever doing it the same way twice.“ever doing it the same way twice.“
-- Christopher Alexander -- Christopher Alexander
![Page 129: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/129.jpg)
A design patternA design patternis a general reusableis a general reusable
solution to a commonly solution to a commonly occurring problem.occurring problem.
![Page 130: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/130.jpg)
A design pattern is not a A design pattern is not a finished design that can be finished design that can be
transformed directly into code.transformed directly into code.
![Page 131: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/131.jpg)
ArchitecturalArchitecturalPatternsPatterns
DesignDesignPatternsPatterns
IdiomsIdioms
![Page 132: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/132.jpg)
Problem: displayProblem: displaya progress bara progress bar
![Page 133: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/133.jpg)
class Something{ protected function performCalculation() { ... foreach ($items as $item) { … process the item … print '.'; } ... }}
![Page 134: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/134.jpg)
Subject/ObserverSubject/Observer
![Page 135: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/135.jpg)
The subject maintains a list of The subject maintains a list of observers and notifies them on observers and notifies them on
status changes.status changes.
![Page 136: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/136.jpg)
interface SplSubject{ public function attach(SplObserver $observer); public function detach(SplObserver $observer);
public function notify();}
![Page 137: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/137.jpg)
interface SplObserver{ public function update(SplSubject $subject);}
![Page 138: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/138.jpg)
class Subject implements SplSubject{ protected $observers;
public function __construct() { $this->observers = new SplObjectStorage(); }
...}
![Page 139: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/139.jpg)
class Subject implements SplSubject{ …
public function attach(SplObserver $observer) { $observers->attach($observer); } public function detach(SplObserver $observer) { $observers->detach($observer); }
...}
![Page 140: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/140.jpg)
class Subject implements SplSubject{ ...
public function notify() { foreach ($this->observers as $observer) { $observer->update($this); } }}
![Page 141: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/141.jpg)
class Something extends Subject implements SplSubject{ public function doWork() { … foreach ($items as $item) { … $this->notify(); } ... }}
![Page 142: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/142.jpg)
class ProgressBar implements SplObserver{ public function update(SplSubject $subject) { print '. '; }}
![Page 143: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/143.jpg)
class Something extends Subject implements SplSubject{ public function doWork() { … foreach ($items as $item) { $this->currentItem = $item; … $this->notify(); } ... }
public function getCurrentItem() { return $this->currentItem() }}
![Page 144: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/144.jpg)
class ProgressBar implements SplObserver{ public function update(SplSubject $subject) { $item = $subject->getCurrentItem(); … }}
![Page 145: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/145.jpg)
class ProgressBar implements SplObserver{ public function update(SplSubject $subject) { $item = $subject->getCurrentItem();
if ($item->isDir()) { print '[' . $item->getPathname() . '] '; }
if ($item->isFile()) { print '.'; } }}
![Page 146: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/146.jpg)
$progressBar = new ProgressBar();
$something = new Something();$something->attach($progressBar);
$something->doWork();
![Page 147: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/147.jpg)
FactoryFactory
![Page 148: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/148.jpg)
Defines an interface for creatingDefines an interface for creatinga family of objects. The concretea family of objects. The concrete
classes that are to be instantiated classes that are to be instantiated are not clearly defined.are not clearly defined.
![Page 149: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/149.jpg)
Creates objects for you.Creates objects for you.
![Page 150: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/150.jpg)
abstract class Plane{ static public function getInstance($type) { return new $type; }}
![Page 151: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/151.jpg)
class Boeing extends Plane{}
class Airbus extends Plane{}
class Boeing777 extends Boeing{}
class AirbusA340 extends Airbus{}
![Page 152: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/152.jpg)
$a = Plane::getInstance('Boeing777');
$b = Plane::getInstance('AirbusA340');
![Page 153: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/153.jpg)
abstract class Plane{ static public function getInstance($type) { switch ($type) { case 'Boeing777': return new Boeing777(); … default:
throw new RuntimeException('...'); } }}
![Page 154: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/154.jpg)
abstract class Plane{ static public function getInstance($type) { if (!in_array($type, array('Boeing777', 'AirbusA340', …))) { throw new RuntimeException('...'); }
return new $type; }}
![Page 155: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/155.jpg)
abstract class Plane{ static public function getInstance($type) { if (!class_exists($type)) { throw new RuntimeException('...'); }
return new $type; }}
![Page 156: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/156.jpg)
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; }}
![Page 157: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/157.jpg)
SingletonSingleton
![Page 158: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/158.jpg)
Limits number of instancesLimits number of instancesof a class to one object.of a class to one object.
![Page 159: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/159.jpg)
Limits number of instancesLimits number of instancesof a class to one object.of a class to one object.
![Page 160: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/160.jpg)
class Singleton{ static protected $instance;
static public function getInstance() { if (is_null(self::$instance)) { self::$instance = new Singleton(); }
return self::$instance; }}
![Page 161: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/161.jpg)
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; }}
![Page 162: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/162.jpg)
class Something{ public function doWork() { $singleton = Singleton::getInstance(); $singleton->... ... }}
![Page 163: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/163.jpg)
class Something{ public function doWork($reference) { $reference->... ... }}
![Page 164: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/164.jpg)
![Page 165: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/165.jpg)
RegistryRegistry
![Page 166: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/166.jpg)
A well-known object usedA well-known object usedby others to find sharedby others to find shared
objects and services.objects and services.
![Page 167: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/167.jpg)
…$db = StaticRegistry::getDbAdapter();...
![Page 168: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/168.jpg)
class StaticRegistry{ static protected $dbAdapter;
static public function getDbAdapter() { if (is_null(self::$dbAdapter)) { self::$dbAdapter = new DbAdapter(); }
return self::$dbAdapter; }}
![Page 169: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/169.jpg)
…$db = Registry::getInstance()->getDbAdapter();...
![Page 170: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/170.jpg)
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; }}
![Page 171: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/171.jpg)
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; }}
![Page 172: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/172.jpg)
MVCMVC
![Page 173: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/173.jpg)
ClassicalClassical
MVCMVC
![Page 174: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/174.jpg)
ModelModel
![Page 175: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/175.jpg)
RepresentsRepresentsdomain-specific datadomain-specific data
![Page 176: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/176.jpg)
View View
![Page 177: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/177.jpg)
RendersRendersmodel datamodel data
![Page 178: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/178.jpg)
ControllerController
![Page 179: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/179.jpg)
Handles eventsHandles eventsand modifies modeland modifies model
![Page 180: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/180.jpg)
PresentationPresentation
LogicLogic
Data AccessData Access MM
VV
CC
![Page 181: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/181.jpg)
Model != Data AccessModel != Data Access
![Page 182: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/182.jpg)
Model != Data AccessModel != Data Access
![Page 183: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/183.jpg)
![Page 184: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/184.jpg)
ControllerController
ModelModelViewView
![Page 185: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/185.jpg)
ControllerController
ModelModelViewView
Controller observes ViewController observes View
![Page 186: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/186.jpg)
ControllerController
ModelModelViewView
Controller fetches data from ViewController fetches data from View
![Page 187: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/187.jpg)
ControllerController
ModelModelViewView
Controller modifies ModelController modifies Model
![Page 188: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/188.jpg)
ControllerController
ModelModelViewView
View observes ModelView observes Model
![Page 189: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/189.jpg)
ControllerController
ModelModelViewView
View fetches data from ModelView fetches data from Model
![Page 190: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/190.jpg)
MVCMVCon the Webon the Web
![Page 191: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/191.jpg)
ServerServer
ClientClient
HTTP RequestHTTP Request HTTP ResponseHTTP Response
VV
CC MM
![Page 192: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/192.jpg)
View is View is remoteremote
![Page 193: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/193.jpg)
ControllerController
ModelModelViewView
![Page 194: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/194.jpg)
ControllerController
ModelModelViewView
Controller can't observe ViewController can't observe View
![Page 195: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/195.jpg)
ControllerController
ModelModelViewView
View can't observe ModelView can't observe Model
![Page 196: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/196.jpg)
ControllerController
ModelModelViewView
FrontFrontControllerController
View doesn't talk to ControllerView doesn't talk to Controller
![Page 197: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/197.jpg)
ControllerController
ModelModelViewView
FrontFrontControllerController
HTTPHTTPRequestRequest
![Page 198: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/198.jpg)
ControllerController
ModelModelViewView
FrontFrontControllerController
HTTPHTTPRequestRequest
execute()execute()
![Page 199: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/199.jpg)
ControllerController
ModelModelViewView
FrontFrontControllerController
HTTPHTTPRequestRequest
execute()execute()
getData()getData()
![Page 200: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/200.jpg)
ControllerController
ModelModelViewView
FrontFrontControllerController
HTTPHTTPRequestRequest
execute()execute()
getData()getData()
setData()
setData()
![Page 201: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/201.jpg)
ControllerControllerselects Viewselects View
![Page 202: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/202.jpg)
View generatesView generatesfull HTML pagefull HTML page
![Page 203: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/203.jpg)
Workflows by Workflows by Controller chainingController chaining
![Page 204: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/204.jpg)
Lean Controller, Lean Controller, Fat ModelFat Model
![Page 205: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/205.jpg)
![Page 206: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/206.jpg)
No data accessNo data accessin Controller or Modelin Controller or Model
![Page 207: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/207.jpg)
No presentationNo presentationin Controller or Modelin Controller or Model
![Page 208: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/208.jpg)
Separation ofSeparation ofConcernsConcerns
![Page 209: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/209.jpg)
Golden Golden RulesRules
![Page 210: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/210.jpg)
„„Hang the rules. Hang the rules. They're more like They're more like guidelines anyway.“guidelines anyway.“
--Elizabeth Swann,--Elizabeth Swann,Pirates of the CaribbeanPirates of the Caribbean
![Page 211: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/211.jpg)
Make Make dependencies dependencies
explicit.explicit.
![Page 212: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/212.jpg)
„„Life can only beLife can only beunderstoodunderstood backwardsbackwards,,but it must be but it must be livedlivedforwardsforwards.“.“
-- Soren Kierkegaard-- Soren Kierkegaard
![Page 213: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/213.jpg)
Solve your Solve your problem.problem.
![Page 214: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/214.jpg)
Do one thingDo one thingat a time.at a time.
![Page 215: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/215.jpg)
Let othersLet othersdo the work.do the work.
![Page 216: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/216.jpg)
Do not care Do not care about others.about others.
![Page 217: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/217.jpg)
Keep itKeep itsimple.simple.
![Page 218: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/218.jpg)
„„Debugging is twice as hardDebugging is twice as hardas writing the code in theas writing the code in thefirst place. Therefore, if youfirst place. Therefore, if youwrite the code as cleverly as write the code as cleverly as possible, you are, by definition, possible, you are, by definition, not smart enoughnot smart enoughto debug it.“to debug it.“
-- Brian W. Kernighan-- Brian W. Kernighan
![Page 219: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/219.jpg)
Do notDo notcomment.comment.
![Page 220: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/220.jpg)
Do notDo notcomment.comment.**
** Some restrictions apply. Some restrictions apply.
![Page 221: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/221.jpg)
””The most important The most important single aspect of software single aspect of software development ...development ...
… is to be … is to be clearclear about about what you are trying to what you are trying to build.”build.”
-- Bjarne Stroustrup-- Bjarne Stroustrup
![Page 222: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/222.jpg)
Name the thing.Name the thing.
![Page 223: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/223.jpg)
„„There's no sense beingThere's no sense beingexact about somethingexact about somethingif you don't even knowif you don't even know
what you're talking about.“what you're talking about.“-- John von Neumann-- John von Neumann
![Page 224: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/224.jpg)
It has to fitIt has to fiton one page.on one page.
![Page 225: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/225.jpg)
””Measuring programming Measuring programming progress by lines of codeprogress by lines of codeis like measuring aircraft is like measuring aircraft building progress by building progress by weightweight.”.”
-- Bill Gates-- Bill Gates
![Page 226: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/226.jpg)
Accept Change.Accept Change.
![Page 227: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/227.jpg)
””I may not have gone I may not have gone where I intended to go, where I intended to go, but I think I have ended but I think I have ended up where I needed to be.“up where I needed to be.“
-- Douglas Adams-- Douglas Adams
![Page 228: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/228.jpg)
Thank you.Thank you.
Please rate me:Please rate me:http://joind.inhttp://joind.in
![Page 229: Advanced OOP and Design Patterns](https://reader036.vdocuments.net/reader036/viewer/2022081720/5469f1c7b4af9f36088b4bdd/html5/thumbnails/229.jpg)
Copyright © 2009 thePHP.cc, Germany
Contact■ http://thePHP.cc■ http://www.priebsch.de■ http://www.slideshare.net/spriebsch■ http://twitter.com/spriebsch■ [email protected], IRC: spriebsch