Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

2009-02 Oops!


Published on

A rehash of a 2003 talk I did given at 2009 at CNET for PHP Meetup.

Published in: Technology
  • Login to see the comments

  • Be the first to like this

2009-02 Oops!

  1. 1. 최태리 <?OOps! The PHP Fear and Loathing Guide to Basic Object-Oriented Design terry chay tagged 11 February 2009 engineering brownbag
  2. 2. 최태리 {introduction 2XtremePeople
  3. 3. 최태리 “PhpPatterns is just that—a source of design patterns for PHP code. Will wonders never cease? I ran this by a Java programmer I know that I have drawn into the PHP world and her comment was, ‘I’d have never even thought to try patterns in PHP.’” —the FuzzyBlog phppatterns? {
  4. 4. object-orientedsnob {
  5. 5. {
  6. 6. Web Developer Training PHP to ASP.NET {
  7. 7. 최태리 “ASP.NET applications are based on a robust Object Oriented Programming (OOP) paradigm rather than a scripting paradigm…The upside of ASP.NET’s support of OOP concepts [vs PHP] means that ASP.NET applications for the most part run better designed code, have clear separation of content, logic, and data and thus are generally easier to support over the long term.” —Migrating from PHP to ASP.NET dotFUD {
  8. 8. 최태리 “Although being a young fellow myself, I have to hold my hand up and say I was educated in an era before design patterns were even invented. Yes it’s true, such a time did exist. In my day, it was called ‘Data Structures’.” —Alan Williamson, Editor-in-Chief November 2002 datastructures? {
  9. 9. grumpyoldprogrammer {
  10. 10. the middle way {
  11. 11. 離 11守 破 threelevels {
  12. 12. 離 12守 破 shuhold chinese character “house” and “law” to abide by; to defend the o-o bigot 7 habits: dependence {
  13. 13. 離 13守 破 habreak chinese character “stone” + phonetic to break the grumpy old programmer 7 habits: independence {
  14. 14. 離 14守 破 rileave chinese character “bird” + phonetic to leave; to depart the middle way 7 habits: interdependence {
  15. 15. Some basic O-O {
  16. 16. 16 myquiz 1:<?php 2:$tests[1] = new stdClass(); 3:$tests[2] = new stdClass(); 4: 5:foreach ($tests as $obj) { 6: $obj->foo = 'bar'; 7:} 8: 9:print_r($tests); 10:?> 1. 2. 3. tychay$ php test.php Array ( [1] => stdClass Object ( ) [2] => stdClass Object ( ) ) { 1. construct some generic PHP objects 2.interate over objects and assign them a value 3.dump the array of objects what do you think the output of this is and why? UNEXPECTED!
  17. 17. 1:<?php 2:$tests[1] = new stdClass(); 3:$tests[2] = new stdClass(); 4: 5:foreach ($tests as $obj) { 6: $obj->foo = 'bar'; 7:} 8: 9:print_r($tests); 10:?> 17 myquiz remember that PHP4, objects are like everything else, so you need the &! Otherwise it will use a copy of the object. {
  18. 18. 1:<?php 2:$tests[1] =& new stdClass(); 3:$tests[2] =& new stdClass(); 4: 5:foreach ($tests as $count=>$obj) { 6: $tests[$count]->foo = 'bar'; 7:} 8: 9:print_r($tests); 10:?> 18 myquiz tychay$ php answer1.php Array ( [1] => stdClass Object ( [foo] => bar ) [2] => stdClass Object ( [foo] => bar ) ) now we’ve fixed the problem! {
  19. 19. 19 byreference { remember this is true also when: prints empty object! 1:<?php 2:class testClass 3:{ 4: function addObject(&$object) 5: { 6: $this->object = $object; 7: } 8:} 9:$testObject =& new testClass(); 10: 11:function addBar($object) 12:{ 13: $object->bar = 'this is set also'; 14:} 15:addBar($testObject); 16: 17:function getSameObject() 18:{ 19: global $testObject; 20: return $testObject; 21:} 22:$returnObject = getSameObject(); 23:$returnObject->same = 'this should be in object'; 24: 25:class testRefClass 26:{ 27: function testRefClass($objFromHell) 28: { 29: $objFromHell->something = 'something here'; 30: $objFromHell->addObject($this); 31: } 32:} 33:$tempObject = new testRefClass($testObject); 34:print_r($testObject); 1. passing parameters 3. constructor 2. functions that return objects
  20. 20. 20 {1:<?php 2:class testClass 3:{ 4: function addObject(&$object) 5: { 6: $this->object = $object; 7: } 8:} 9:$testObject =& new testClass(); 10: 11:function addBar(&$object) 12:{ 13: $object->bar = 'this is set also'; 14:} 15:addBar($testObject); 16: 17:function &getSameObject() 18:{ 19: global $testObject; 20: return $testObject; 21:} 22:$returnObject =& getSameObject(); 23:$returnObject->same = 'this should be in object'; 24: 25:class testRefClass 26:{ 27: function testRefClass(&$objFromHell) 28: { 29: $objFromHell->something = 'something here'; 30: $objFromHell->addObject($this); 31: } 32:} 33:$tempObject =& new testRefClass($testObject); 34:print_r($testObject); byreference remember this is true also when: 1. passing parameters 3. constructor 2. functions that return objects PHP5 fixes this!
  21. 21. 최태리 “…the new object model makes object oriented programming in PHP much more powerful and intuitive. No longer will you have to mess with cryptic & characters to get the job done. No longer will you have to worry about whether changes you made to the object inside the constructor will survive the dreaded new-operator behavior… php5 {
  22. 22. 최태리 …No longer will you ever have to stay up until 2:00AM tracking elusive bugs!” —Zeev Suraski November 2002 php5 { Zeev’s2AMbug
  23. 23. 최태리 23 staticproperties no static class variables in PHP. substitute with global variables static function variables (bad idea) {
  24. 24. 24 globalstatic bind by reference in constructor (or elsewhere) 1:<?php 2:$GLOBALS['_statics']['testClass']['staticCount'] = 0; 3:class testClass 4:{ 5: var $staticCount; 6: function testClass() 7: { 8: $this->staticCount =& $GLOBALS['_statics'] ['testClass']['staticCount']; 9: } 10: function increment() 11: { 12: return ++$this->staticCount; 13: } 14:} 15:$test1 =& new testClass(); 16:$test2 =& new testClass(); 17:$test1->increment(); 18:$test2->increment(); 19:print_r($test1); 20:print_r($test2); 21:echo testClass::increment(); 22:?> tychay$ php test3.php testclass Object ( [staticCount] => 2 ) testclass Object ( [staticCount] => 2 ) 1 watch out though!
  25. 25. 25 singleton one of the simplest patterns creates a single instance of a class (DB connection) lazy evaluation flexible 1:<?php 2:class testSingleton 3:{ 4: function &instance() 5: { 6: static $singleton; 7: if (!$singleton) { 8: $singleton =& new testSingleton(); 9: } 10: return $singleton; 11: } 12:} 13:$test1 =& testSingleton::instance(); 14:$test1->foo = bar; 15:$test2 =& testSingleton::instance(); 16:print_r($test2); 17:?> tychay$ php test4.php testsingleton Object ( ) watch out though!
  26. 26. 26 singleton also note the liberal use of & 1:<?php 2:$GLOBALS['_statics']['testSingleton']['singleton'] = null; 3:class testSingleton 4:{ 5: function &instance() 6: { 7: if (is_null($GLOBALS['_statics']['testSingleton'] ['singleton'])) { 8: $GLOBALS['_statics']['testSingleton']['singleton'] =& new testSingleton(); 9: } 10: return $GLOBALS['_statics']['testSingleton'] ['singleton']; 11: } 12:} 13:$test1 =& testSingleton::instance(); 14:$test1->foo = bar; 15:$test2 =& testSingleton::instance(); 16:print_r($test2); 17:?> tychay$ php test5.php testsingleton Object ( [foo] => bar )
  27. 27. 27 latebinding when a polymorphic call is resolved at run time (instead of compile time) oo-bigots advocate against (speed, strong typing) simple to do in PHP 1:<?php 2:class testLateBinding 3:{ 4: function callMeLate() 5: { 6: echo "I was calledn"; 7: $this->wasCalled = true; 8: } 9:} 10:$object1 =& new testLateBinding(); 11:$object2 =& new testLateBinding(); 12:$functionname = 'callMeLate'; 13: 14:$object1->{$functionname}(); 15: 16:call_user_func(array(&$object2,$functionname)); 17:print_r($object2); 18:?> tychay$ php test6.php I was called I was called testlatebinding Object ( [wasCalled] => 1 ) variable-variables call_user_func() PHP4.3+ note the &!. {
  28. 28. 28 一 三 二 roadmap
  29. 29. 29 一 三 二 the why why do old metaphors fail? why use agile processes? methodology
  30. 30. 30 一 三 二 the what what are the precepts of class rules what are the parameters of package design what are patterns? principles
  31. 31. 31 一 三 二 the how how do patterns allow me to follow principles? how can patterns work around a design error? how do patterns apply to more than O-O? patterns
  32. 32. 최태리 methodology 一 최채리
  33. 33. metaphors 一
  34. 34. 一 34 codecomplete Published 1993 Microsoft “Tome” Award winning book
  35. 35. 35 paradigm shift Code Complete is a “wanna be” Structure of Scientific Revolutions he uses “paradigm shift” Key premise: key metaphor of software should be construction 一
  36. 36. 최태리 36 straw men The metaphor of construction is so central to the book, that the subtitle is: “A Practical Handbook of Software Construction.” Thus it needs to construct some straw men of failed metaphors in order to prove why we should adopt the “software as construction” paradigm. 一
  37. 37. 최태리 37 一 penmanship “writing code” causes expensive trial and error focused on originality > reuse “plan to throw one away” “it might have been state-of-the-art software-engineering practice in 1975”
  38. 38. 2.softwarefarming 一
  39. 39. 최태리 39 growing a system “piece by piece” bad metaphor! fertilizing a system plan? thinning the detailed design? increasing code yields through effective land managment? harvesting code? rotating in a crop of assembler? Who ever believed this shit? 一
  40. 40. 최태리 why Code Complete sucks software as construction 一
  41. 41. The #1 reason why software is not construction 一 離 守 破
  42. 42. Mythical Man Month This is a really famous essay from 1975. Does the year sound familiar? Yes, the Frederick Brooks is the same engineer treated with derision in Code Complete’s “Software as Writing” straw man. A lot of what he says was controversial, but one thing that was never denied was the man-month was a myth. What is a mythical man month? 一
  43. 43. 43 man-month 一the premise is that men and months are interchangeable. This means that in order to reach a deadline I simply add people to the project.
  44. 44. 최태리 44 man-month myth The problem: Adding people to a late project makes it later! first consider case where they’re everything is partition-able (man- month). then add constant time for training then add communication: n(n-1)/2 compare with unpartitionable (single man) 최채리
  45. 45. 45 where? man-hour (măn’our') n. An industrial unit of production equal to the work one person can produce in an hour. Source: The American Heritage® Dictionary of the English Language, Fourth Edition fromconstruction! 一 programming!=labor
  46. 46. 최태리 46 Mythical Man-Month referred to five times in Code Complete Including having the author give an endorsement on the back cover! irony php{con 최채리
  47. 47. 최태리 47 최채리 “I’d be astonished if the open-source community has in total done as many man-years of computer security code reviews as we have done in the last two months” —Steven Lipner, Director of Security Assurance, Microsoft (April 8th, 2002) persistantmyth
  48. 48. asengineering software… 一
  49. 49. 최태리 49 “The final goal of any engineering activity is some type of documentation. When a design effort is complete, the design documentation is turned over to the manufacturing team. If the design documents truly represent a complete design, the manufacturing team can proceed to build the product.” —Jack Reeves, C++ Journal, 1992 一
  50. 50. 최태리 50 “Two Irreparable Mistakes of thre Software Field: 1. The believe that the source code is a development product, not the design for a product.” —Michael Feathers, ObjectMentor The other problem with software as construction: the “design” phase finishes with working source code it’s based on the illusion that the source code is the product! 一
  51. 51. 최태리 51 How did we buy this illusion? “It is cheaper and simpler to build the design and test it than do anything else. We do not care how many builds we do —they cost next to nothing…No other modern industry would tolerate a rework rate of over 100% in its manufacturing process” —Jack Reeves, C++ Journal, 1992 a software “build” means “manufacturing” phase is cheap. 一
  52. 52. 최태리 離 守 破 A software developer is more akin to an artist than an assembly line worker… Throwing more people into the design mix can be counterproductive. —Jason Burkert “Software as engineering” accepts the reality of the mythical man-month! The source code is the design. 離 一
  53. 53. 53 roadmap 一 三 二 now that we’ve talked discussed the paradigm or metaphor it is time to apply that to programming practice.
  54. 54. 54 heavyweight 離 守 破 methodologies like ISO9001 violate “software as an engineering” by definition treat auxiliary documentation as the product
  56. 56. 56 changing requirements constant release schedule not life-death “The reason why dynamic languages like Perl, Python, and PHP are so important … Unlike applications from the previous paradigm, web applications are not released in one to three year cycles. They are updated every day, sometimes every hour.” —Tim O’Reilly, 14 May 2003 websoftware 一
  57. 57. 최태리 57 “The biggest mistake in ‘Build one to throw away’ concept is that it implicitly assumes the classical sequential or waterfall model of software construction.” —Frederick Brooks, Mythical Man- Month, 20th Aniv. 1995 moreirony 一
  58. 58. agility 一
  59. 59. 59 XP 離 守 破 ship early and often! one of many lightweight methodologies known as “agile” I’ll cover three features of XP. So you get an idea of what is considered an “agile” process 一
  60. 60. 1.Test-First Design 一
  61. 61. designbytest recall the waterfall process. Look at where the unit testing is. recall the “software as engineering” metaphor: tests and builds are cheap. Why aren’t we leveraging it? We should be testing first and using testing as a design technique (the hard part of engineering), not a testing technique (easy part). SYSTEM SPECIFICATION REQUIREMENTS ANALYSIS ARCHITECTURAL DESIGN CODING AND DEBUGGING DETAILED DESIGN UNIT TESTING SYSTEM TESTING MAINTAINENCE 一
  62. 62. 1:<?php 2:class MoneyBagTest extends TestCase { 3:    var $m12CHF; 4:    var $m14CHF; 5:    var $m28USD; 6:    var $mArray1; 7:    var $moneybag1; 8:    var $moneybag2; 9: function MoneyBagTest( $name = "MoneyBagTest" ) { 10: $this->TestCase( $name ); 11: } 12: 13: function setUp() { 14: $this->m12CHF = new Money( 12, "CHF" ); 15: $this->m14CHF = new Money( 14, "CHF" ); 16: } 17: function tearDown() { 18: $this->m12CHF = NULL; 19: $this->m14CHF = NULL; 20: $this->m28USD = NULL; 21: } 22: 23: function testSimpleAdd() { 24: $result = $this->m12CHF->add( $this->m14CHF ); 25: $this->assert(new Money(27,"CHF"), $result, "This should fail" ); 26: $this->assertEquals(new Money(27,"CHF"), $result, "This should fail" ); 27: } 28: 29: // insert more tests here: use "test..." for name of function. 30:} 62 code unit test first 1. Code the Unit Test First 2. Write minimum code until test works 3. Refactor (see later) 4. Rerun tests constructor a test 一 fixture
  63. 63. keep the bar green to keep the code clean… 31: 32:$test = new MoneyBagTest(); 33:$testRunner = new TestRunner(); 34:$testRunner->run($test); 35:?>一
  64. 64. 2.Refactoring 一
  65. 65. 최태리 65 “The process of changing a software system in such a way that does not alter the external behavior of the code yet improves the internal structure” —Martin Fowler, Refactoring, 1999 the changes by themselves are tiny focus on simplicity (in design) not simplistic (implementation) refactorit! 一
  66. 66. 최태리 66 do this continuously purpose of a module of code: function it performs allow change communicate prevents code rot in large projects my experience. refactorit! 一
  67. 67. 3.You Aren’t Going to Need It (YAGNI) 一
  68. 68. 최태리 68 Implement the simplest thing that could possibly work. Basically, if you need it, you can put it in later—it does not “save time.” Set aside your fears about tomorrow and concentrate on today. whatisYAGNI?
  69. 69. 최태리 69 YAGNIperks keeps system smaller and easier to understand (form of refactoring) more likely to ship out the door if you focus on needs allows for system accretion recall how fast a web iteration vs. Big Bang
  70. 70. 최태리 70 “A project done in Java will cost 5 times as much, take twice as long, and be harder to maintain than a project done in a scripting language such as PHP or Perl,” —Philip Greenspun 20 September 2003
  71. 71. 최태리 71 lack of rigid O-O definitely a plus! recall the “Migrating from PHP to dotNET” document lack of framework definitely a plus! phpYAGNI
  72. 72. 72 Well bad pattern for a loosly typed language such as PHP! Iterator Pattern: provide a way to access the element of an aggregate object sequentially without exposing its underlying representation badpattern Aggregate CreateIterator() ConcreteAggregate + CreateIterator() Iterator + First() + Next() + IsDone() + CurrentItem() ConcreteIterator return new ConcreteIterator(&$this)
  73. 73. 1:<?php 2://A lot of code in here... 3:include(ECLIPSE_ROOT.'ArrayIterator.php'); 4: 5:$iterator =& new ArrayIterator(&$arrayToBeIterated); 6:while ($element=$iterator->getCurrent()) { 7: echo $iterator->key().' => '.$element; 8: $iterator->next(); 9:} 10:$iterator->reset(); 11: 12:?> iterator# phpdefault You can vary what is being iterated over (ignoring constructor) YAGNI! If you must have an iterator there is SPL in PHP5! 1:<?php 2:foreach($arrayToBeIterated as $key=>$value) { 3: echo $key.' => '.$value; 4:} 5:?>
  74. 74. 최태리 74 pair programming the planning game/user-stories code reviews acceptance tests on-site customer other processes: SCRUM, Crystal, etc. code ownership XPnotcovered 一
  75. 75. 75 roadmap 一 三 二 the metaphor/paradigm for building software is engineering we now know agility: the lightweight processes that avoid the waterfall process 離 守 破
  76. 76. 76 roadmap 一 三 二 What programming principles help us program correctly?
  77. 77. 최태리 principles 二
  78. 78. 78 roadmap 一 三 二 1. What precepts for class design? 2. Grouping classes into packages using what parameters? 3. What are patterns?
  79. 79. precepts of classes 二
  80. 80. 최태리 80 single responsibility A class should have only one reason to change. Each responsibility is an axis of change. more than one responsibility = coupling 二
  81. 81. 81 violation PEAR is great. Except… This is the PEAR Error constructor. Note that this method causes the object to violate SRP! 2:function PEAR_Error($message = 'unknown error', $code = null, 3: $mode = null, $options = null, $userinfo = null) 4:{ 5: if ($mode === null) { 6: $mode = PEAR_ERROR_RETURN; 7: } 8: $this->message = $message; 9: $this->code = $code; 10: $this->mode = $mode; 11: $this->userinfo = $userinfo; 12: if (function_exists("debug_backtrace")) { 13: $this->backtrace = debug_backtrace(); 14: } 15: if ($mode & PEAR_ERROR_CALLBACK) { 16: $this->level = E_USER_NOTICE; 17: $this->callback = $options; 18: } else { 19: if ($options === null) { 20: $options = E_USER_NOTICE; 21: } 22: $this->level = $options; 23: $this->callback = null; 24: } 25: if ($this->mode & PEAR_ERROR_PRINT) { 26: if (is_null($options) || is_int($options)) { 27: $format = "%s"; 28: } else { 29: $format = $options; 30: } 31: printf($format, $this->getMessage()); 32: } 33: if ($this->mode & PEAR_ERROR_TRIGGER) { 34: trigger_error($this->getMessage(), $this->level); 35: }
  82. 82. 82 and the violation goes on callbacks die return mode print trigger_error exception 36: if ($this->mode & PEAR_ERROR_DIE) { 37: $msg = $this->getMessage(); 38: if (is_null($options) || is_int($options)) { 39: $format = "%s"; 40: if (substr($msg, -1) != "n") { 41: $msg .= "n"; 42: } 43: } else { 44: $format = $options; 45: } 46: die(sprintf($format, $msg)); 47: } 48: if ($this->mode & PEAR_ERROR_CALLBACK) { 49: if (is_string($this->callback) && strlen($this- >callback)) { 50: call_user_func($this->callback, $this); 51: } elseif (is_array($this->callback) && 52: sizeof($this->callback) == 2 && 53: is_object($this->callback[0]) && 54: is_string($this->callback[1]) && 55: strlen($this->callback[1])) { 56: @call_user_func($this->callback, $this); 57: } 58: } 59: if (PEAR_ZE2 && $this->mode & PEAR_ERROR_EXCEPTION) { 60: eval('throw $this;'); 61: } 62:} 63:?>
  83. 83. 최태리 83 Liskov substitution Subtypes must be substitutable for their base types. not an “is-a” relationship validation of LSP occurs in the client! (Design By Contract). 二
  84. 84. 최태리 84 Design By Contract validates Liskov Substituion. What validates Design by contract? Unit Tests! Remember them? They determine define it. In fact, PEAR PHPUnit can document a Design By Contract by reading the unit test (aka TestDox). 1:<?php 2:require_once 'PHPUnit/Framework/TestCase.php'; 3: 4:class FooTest extends PHPUnit_Framework_TestCase 5:{ 6:    public function testIsASingleton() {} 7:    public function testAReallyLongNameIsAGoodThing() {} 8:} 9:?> Foo - Is a singleton - A really long name is a good thing
  85. 85. I violate LSP Look at how naïve this diagram is. It’s the most obvious one but focuses on the physical objects instead of their behaviors. The objects are defined in terms of the clients. Think about an image coming back from the camera, or trying to set a dimmer to a light switch that turns on or off only. Unfortunately I had to live with it for reasons later. Common CameraSwitchable Sensor HVAC
  86. 86. 최태리 86 otherprecepts Open-Closed Principle Dependency-Inversion Principle Interface Segregation Principle 二
  87. 87. parameters of packages 二
  88. 88. 최태리 88 “A few days ago, I was at Microsoft, and they held an amazing conference…After this conference, I was kinda depressed about the future of PHP and Apache… The ASP.NET stuff is just perfect. Fast, Secure and Robust. ASP.NET technology is better than PHP technology.” —Sterling Hughes 5 June 2003 二
  89. 89. 최태리 Common language Runtime access to COM+ server ui controls “code behind” (.cs) server-side object model event-driven handlers automatic page state (ViewState) built-in Validation object try-catch 二
  90. 90. 최태리 built-in authentication (Web.config) built-in database abstraction (ADO.NET) + connection pooling + data binding built-in MSXML: DOM, XSLT, SAX + Web Services auto targeting of HTML IDE (Visual Studio .NET) built-in output caching I see what Sterling is saying! However… 二
  91. 91. 최태리 Common Language Runtime 2nd class, compiling cache, Pint (Parrot) access to COM+ access to COM, Java, C/C++ extensions, mono, command line server ui controls,“ViewState”- saving form state PEAR::HTML_* (Form, Menu, Page…) + others + BYO “code behind” smarty, fasttemplate, flexy, it, phplib, + others, BYO server-side object model session, __sleep(), __wakeup(), SRM event driven handlers bad idea, fusebox + zillions of others, s9y, BYO output-caching zend accelerator, Cache, Cache_Lite, free energy, BYO validation object PEAR::Validate + zillions of others try-catch in PHP5. no substitute for proper error handling “Web.config”- authentication auth, LiveUser, + others ADO.Net- database abstraction db specific, dbx, PEAR DB, MDB, ADODB connection pooling, data-binding pconnect, SRM, only nice on client-side MSXML expat, DOM, SimpleXML, XMLtree etc., 2 SOAP, 5 XMLRPC VisualStudio- IDE Komodo, Zend+ others, text editors
  92. 92. 최태리 92 離 守 破 All of them (or equivalent) can be done in PHP . I have a choice on a solution—Zend’s solution doesn’t bankrupt someone else’s (or me!) Most solutions are open source so I don’t have be tied to someone else’s release-upgrade cycle. ASP.NET’s large framework violates YAGNI—encourages o-o bigotry and bad design. 二
  93. 93. 최태리 93 Comparing PHP to ASP.NET is like comparing the Linux kernel to the Windows Platform. GNU/Linux is the kernel + toolchain. That toolchain is based on a lot of small interacting programs that can be chained to create complex behavior. Windows does the complicated approach. we say Unix has… 二
  94. 94. cohesion vs coupling. 二
  95. 95. 최태리 95 Frameworks vs. Libraries A good package is highly cohesive but weakly coupled. This creates high reusability. Remember the J2EE taking 5x as long to build? This is why. Too much framework. When you use one part of a package, you reuse them all. This is why PEAR succeeds… 二
  96. 96. 최태리 Some of these frameworks are great, but the best are reused entirely (i.e. shrink-wrapped). and Frameworks fail Ariadne, Binary Cloud, Back-End, bBlog, COWeb, Eocene, ezPublish, FastFrame, FUDforum, ISMO, Komplete, LogiCreate Application Server, Mambo, MetaL, Midgard, more.groupware, NetUse, Nucleus, phpGroupWare, Phrame, PostNuke, PHPortal, phpWebSite, Rodin, SiteManager, serendipity, STPHPLib, tikiwiki, TUTOS, WordPress, XOOPS… 二
  97. 97. acyclic dependency 二
  98. 98. depend on stability 二
  99. 99. 최태리 99 this covers acyclic dependency the more you depend on a package the more stable it must be (think client- centric) recall my devices diagram… Common CameraSwitchable Sensor HVAC 二
  100. 100. 최태리 100 Caveat: I’m going to use that bad “construction” analogy… The Leaning Tower of Pisa was built on a shifting foundation. It’s been leaning since before it was finished. Sounds like the what happens when you you try to extend someone else’s framework. 二
  101. 101. 최태리 101 This is a mapping of the PEAR XML package dependencies. Notice how weakly coupled they are. Notice the packages which are depended on. What happens if the API is changed. What if you depend on them? Better have your Unit Tests! XML_ParserXML_Util XML_Beautifier XML_CSSML XML_Tree XML_DTD XML_fo2pdf XML_HTMLSax XML_image2sv g XML_NITF XML_RSS XML_SaxFilters XML_Serializer XML_sql2xml XML_Statistics XML_RDDL 二
  102. 102. 102 roadmap 一 三 二 we now know the precepts by which classes are made and the parameters by whic they are packaged into classes… 離 守 破
  103. 103. 103 roadmap 一 三 二 Before we go discuss patterns it helps to define what a pattern is! If we skip this then we run the danger of becoming a o- o bigot or a grumpy old programmer! 離 守 破
  104. 104. what are patterns? 二
  105. 105. 최태리 105 Patterns come from a book on architecture: “Each 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, The Timeless Way of Building, 1979 二
  106. 106. 최태리 106 I don’t know architecture. It makes me think of the software construction metaphor Let’s find some patterns closer to us… Web Design! whatever!
  107. 107. cookie crumbs solve deeply hierarchical navigation
  108. 108. tabs solve lateral navigation along a few high level elements
  109. 109. tabs can use a million times over, without ever doing it the same way twice
  110. 110. 최태리 110 二definedbycontext Let’s not be an o-o snob. “tabs” and “cookie crumbs” are both navigational patterns. Which one is best to use is defined by context.
  111. 111. patterns are designed to be linked together 二
  112. 112. phpunitpatterndensity 二
  113. 113. 최태리 patterns 三
  114. 114. 최태리 ?baddesign tale of the keyfob 三
  115. 115. 115 mybane Recall my poor design choice. Now realize that a KeyFob has four buttons. Each one is a sensor. Since I implemented the low level stuff blindly and this error occurred on the presentation tier, the user sees one keyfob as four devices. One for each button! Common CameraSwitchable Sensor HVAC 三
  116. 116. 최태리 How to make four devices appear as one ? 三
  117. 117. 최태리 !a pattern a day keeps the pink slip away composite pattern 三
  118. 118. 최태리 118 Common Aggregate A composite pattern adds a subclass that contains 1 or more elements of the base class. Thus it appears to clients as a single object, even though it contains more than one and have to handle the objects behind the scenes. Common CameraSwitchable Sensor HVAC 三
  119. 119. anotherexample三
  120. 120. 최태리 ?phpdoc decoupled messaging 三
  121. 121. 121 phpDocu phpDocumentor is a PEAR librar y/application that tokenizes and parses your PHP code for JavaDoc style comments and uses them to build hyperlinked API docs. The problem is the parsers (preg, tokenizer, c-based) and the renderers (various HTML, peardoc, XML, PDF) both will need to vary in the PHP5 version. The event messaging that occurs can get quite complex. 三
  122. 122. 최태리 How to make a more robust messaging system ? 三
  123. 123. 최태리 !allow one object to notify many (run-time config) observer pattern 三
  124. 124. 최태리 124 An observer registers with the subject for notification using the attach() method passing itself. The subject notifies all observers by calling its notify() which iterates over all observers and calls its update() method You can pass $this to update() to allow observer to use subject. Subject + attach(&$observer) + detatch(&$observer) # notify() Observer + update() ConcreteObserver + update() ConcreteSubject 0..1* 三
  125. 125. 최태리 ?templates working friendly with designers 三
  126. 126. 126 shutemplate dotNet’s serverui controls and auto page state are great but they’re template systems however PHP IDE != Visual Studio 離 守 破 三
  127. 127. 127 1:<html> 2:<head> 3: <title>Example ASP.NET template</title> 4:</head> 5:<body> 6:<script language="VB" runat="server"> 7:Sub Page_Load(sender As Object, e As EventArgs) 8: TheDate.Text = DateTime.Now 9:End Sub 10:</script> 11: <p>The current date is: <asp:Label id="TheDate" runat="server" />.</p> 12:</body> 13:</html> 三 shu how does this render in an editor? how does it separate model-view-controller? does MVC really matter anyway?…
  128. 128. 최태리 128 “With Web applications, nearly all the engineering happens in the SQL database and the interaction design, which is embedded in the page flow links. None of the extra power of Java is useful…” —Philip Greenspun 2003 September 20 三
  129. 129. 129 hatemplate PHP is itself a templating language. if all web developers are PHP programmers this makes the most sense however 離 守 破 三
  130. 130. 1:<html> 2:<head> 3: <title>Example ASP.NET template</title> 4:</head> 5:<body> 6:<script language="VB" runat="server"> 7:Sub Page_Load(sender As Object, e As EventArgs) 8: TheDate.Text = DateTime.Now 9:End Sub 10:</script> 11: <p>The current date is: <asp:Label id="TheDate" runat="server" />.</p> 12:</body> 13:</html> 1:<html> 2:<head> 3: <title>Example simple PHP version</title> 4:</head> 5:<body> 6: <p>The current date is: <?php echo date('l, F dS, y'); ?>.</p> 7:</body> 8:</html> 三 shu ha much smaller and easier to read! how does a web designer deal with it?
  131. 131. 최태리 !doing templates without o-o freeenergy 三
  132. 132. 132 ritemplate 1. check for compiled version. 2. if compiled then include compiled version 3. if not compiled then call routine to compile template 4. use XML! 離 守 破 三
  133. 133. 133 1:<?php 2:tc::import('tips'); 3:tc::import('tc.error'); 4: 5:$template =& new tips(); 6:$template->assign('date',date('l, F dS, y')); 7:$template->output('tipsexample.html'); 8:?>Separate templates = separate files leverages shu This is a smarttemplate like system leverages ha of php use XML so the web developer can work with 1:<tips:template> 2:<html> 3:<head> 4: <title>Example PHP template</title> 5:</head> 6:<body> 7: <p>The current date is: <tips:variable name="date">Wednesday, October 21st, 2003</ tips:variable>.</p> 8:</body> 9:</html> 10:</tips:template> 三
  134. 134. 최태리 }conclusion 三
  135. 135. 최태리 ?>questions AndAnswers 三