135
태리 <? OOps! The PHP Fear and Loathing Guide to Basic Object -Oriented Design terry chay tagged 11 February 2009 engineering brownbag

2009-02 Oops!

Embed Size (px)

Citation preview

Page 1: 2009-02 Oops!

최태리

<?OOps! The PHP Fear and

Loathing Guide to Basic Object-Oriented Design

terry chaytagged

11 February 2009engineering brownbag

Page 2: 2009-02 Oops!

최태리

{introduction2XtremePeople

Page 3: 2009-02 Oops!

최태리

“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? {

Page 4: 2009-02 Oops!

object-orientedsnob

{

Page 5: 2009-02 Oops!

{

Page 6: 2009-02 Oops!

Web Developer Training

PHP to ASP.NET

{

Page 7: 2009-02 Oops!

최태리

“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 {

Page 8: 2009-02 Oops!

최태리

“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-ChiefNovember 2002

datastructures? {

Page 9: 2009-02 Oops!

grumpyoldprogrammer

{

Page 10: 2009-02 Oops!

the middle way

{

Page 11: 2009-02 Oops!

11守

threelevels{

Page 12: 2009-02 Oops!

12守

shuhold

chinese character “house” and “law”

to abide by; to defend

the o-o bigot

7 habits: dependence

{

Page 13: 2009-02 Oops!

13守

habreakchinese character “stone” + phonetic

to break

the grumpy old programmer

7 habits: independence

{

Page 14: 2009-02 Oops!

14守

rileave

chinese character “bird” + phonetic

to leave; to depart

the middle way

7 habits: interdependence

{

Page 15: 2009-02 Oops!

Some basic O-O

{

Page 16: 2009-02 Oops!

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 objects2.interate over objects and assign them a value3.dump the array of objects

what do you think the output of this is and why?

UNEXPECTED!

Page 17: 2009-02 Oops!

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.

{

Page 18: 2009-02 Oops!

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!

{

Page 19: 2009-02 Oops!

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); 36:?>

1. passing parameters

3. constructor

2. functions that return objects

Page 20: 2009-02 Oops!

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); 36:?>

byreferenceremember this is true also when:

1. passing parameters

3. constructor

2. functions that return objects

PHP5 fixes this!

Page 21: 2009-02 Oops!

최태리

“…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 {

Page 22: 2009-02 Oops!

최태리

…No longer will you ever have to stay up until 2:00AM tracking elusive bugs!”

—Zeev SuraskiNovember 2002

php5 {

Zeev’s2AMbug

Page 23: 2009-02 Oops!

최태리23

staticproperties

no static class variables in PHP.

substitute with

global variables

static function variables (bad idea)

{

Page 24: 2009-02 Oops!

24

globalstaticbind 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!

Page 25: 2009-02 Oops!

25

singletonone 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!

Page 26: 2009-02 Oops!

26

singletonalso 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 )

Page 27: 2009-02 Oops!

27

latebindingwhen 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 called\n"; 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-variablescall_user_func()

PHP4.3+note the &!.

{

Page 28: 2009-02 Oops!

28一

三二

roadmap

Page 29: 2009-02 Oops!

29一

三二

the why

why do old metaphors fail?

why use agile processes?

methodology

Page 30: 2009-02 Oops!

30一

三二

the what

what are the precepts of class rules

what are the parameters of package design

what are patterns?

principles

Page 31: 2009-02 Oops!

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

Page 32: 2009-02 Oops!

최태리

methodology一

최채리

Page 33: 2009-02 Oops!

metaphors

Page 34: 2009-02 Oops!

34

codecomplete

Published 1993

Microsoft “Tome”

Award winning book

Page 35: 2009-02 Oops!

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

Page 36: 2009-02 Oops!

최태리

36 straw men

The metaphor o f construction is so central to the book, that the subtitle is: “A Practical Handbook of Software Construction.”

Thus i t needs to construct some straw men of failed metaphors in order to prove why we should adopt the “ so f tware a s construction” paradigm.

Page 37: 2009-02 Oops!

최태리37

一 1.software 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”

Page 38: 2009-02 Oops!

2.softwarefarming

Page 39: 2009-02 Oops!

최태리

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?

Page 40: 2009-02 Oops!

최태리

why Code Complete sucks

software as construction

Page 41: 2009-02 Oops!

The #1 reason why software is not construction

一離

Page 42: 2009-02 Oops!

Mythical Man Month

This is a really famous essay from 1975. Does the year sound fami l i a r ? 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 wa s a myth . What is a mythical man month?

Page 43: 2009-02 Oops!

43 man-month

一the premise is that men and months a re interchangeable.

This means that in order to reach a deadline I simply add people to the project.

Page 44: 2009-02 Oops!

최태리

44man-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)

최채리

Page 45: 2009-02 Oops!

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

Page 46: 2009-02 Oops!

최태리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

최채리

Page 47: 2009-02 Oops!

최태리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

Page 48: 2009-02 Oops!

asengineeringsoftware…

Page 49: 2009-02 Oops!

최태리

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

Page 50: 2009-02 Oops!

최태리

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!

Page 51: 2009-02 Oops!

최태리

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.

Page 52: 2009-02 Oops!

최태리

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.

Page 53: 2009-02 Oops!

53

roadmap

三二

now that we’ve talked discussed the paradigm or metaphor it is time to apply that to programming practice.

Page 54: 2009-02 Oops!

54

heavyweight離

methodologies like ISO9001 violate “software as an engineering”

by definition

treat auxiliary documentation as the product

Page 55: 2009-02 Oops!

55

Note influence of construction metaphor

BDUF: Big Design Up Front

Big Bang Delivery

waterfall

SYSTEM

SPECIFICATION

REQUIREMENTS

ANALYSIS

ARCHITECTURAL

DESIGN

CODING AND

DEBUGGING

DETAILED DESIGN

UNIT TESTING

SYSTEM TESTING

MAINTAINENCE

from Code Complete, p.3

BDUF

Big Bang

Page 56: 2009-02 Oops!

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 pre v ious parad igm, 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

Page 57: 2009-02 Oops!

최태리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一

Page 58: 2009-02 Oops!

agility

Page 59: 2009-02 Oops!

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

Page 60: 2009-02 Oops!

1.Test-First Design

Page 61: 2009-02 Oops!

designbytest

recall the waterfall process. Look at where the unit testing is.

r eca l l the “ so f tware a s 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

Page 62: 2009-02 Oops!

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:} 31:

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

Page 63: 2009-02 Oops!

keep the bar green to keep the code clean…

30:} 31: 32:$test = new MoneyBagTest(); 33:$testRunner = new TestRunner(); 34:$testRunner->run($test); 35:?> 一

Page 64: 2009-02 Oops!

2.Refactoring

Page 65: 2009-02 Oops!

최태리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!一

Page 66: 2009-02 Oops!

최태리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!一

Page 67: 2009-02 Oops!

3.You Aren’t Going to Need It (YAGNI)

Page 68: 2009-02 Oops!

최태리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?

Page 69: 2009-02 Oops!

최태리69

YAGNIperkskeeps 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

Page 70: 2009-02 Oops!

최태리

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

Page 71: 2009-02 Oops!

최태리71

lack of rigid O-O definitely a plus!

recall the “Migrating from PHP to dotNET” document

lack of framework definitely a plus!

phpYAGNI

Page 72: 2009-02 Oops!

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

badpatternAggregate

CreateIterator()

ConcreteAggregate+ CreateIterator()

Iterator+ First()+ Next()+ IsDone()+ CurrentItem()

ConcreteIterator

return new ConcreteIterator(&$this)

Page 73: 2009-02 Oops!

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:?>

Page 74: 2009-02 Oops!

최태리74

pair programming

the planning game/user-stories

code reviews

acceptance tests

on-site customer

other processes: SCRUM, Crystal, etc.

code ownership

XPnotcovered一

Page 75: 2009-02 Oops!

75

roadmap

三二

the metaphor/paradigm for building software is engineering

we now know agility: the lightweight processes that avoid the waterfall process

Page 76: 2009-02 Oops!

76

roadmap

三二

What programming principles help us program correctly?

Page 77: 2009-02 Oops!

최태리

principles二

Page 78: 2009-02 Oops!

78

roadmap

三二

1. What precepts for class design?

2. Grouping classes into packages using what parameters?

3. What are patterns?

Page 79: 2009-02 Oops!

precepts of classes

Page 80: 2009-02 Oops!

최태리80

single responsibility

A class should have only one reason to change.

Each responsibility is an axis of change.

more than one responsibility = coupling

Page 81: 2009-02 Oops!

81

violationPEAR 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: } 36: if ($this->mode & PEAR_ERROR_DIE) {

Page 82: 2009-02 Oops!

82

and the violation goes on

callbacks

die

return mode

print

trigger_error

exception

35: } 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:?>

Page 83: 2009-02 Oops!

최태리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).

Page 84: 2009-02 Oops!

최태리

84

Design By Contract va l idates L i sko v Subst i tu ion . What va l idates Des ign by contract?

Unit Tests! Remember them? They determine define it.

In fact, PEAR PHPUnit can document a Design By Contract by reading the un i t te s t (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

Page 85: 2009-02 Oops!

I violate LSP

Look a t how na ïve th i s 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

Page 86: 2009-02 Oops!

최태리86

otherprecepts

Open-Closed Principle

Dependency-Inversion Principle

Interface Segregation Principle

Page 87: 2009-02 Oops!

parameters of packages

Page 88: 2009-02 Oops!

최태리

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

Page 89: 2009-02 Oops!

최태리

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

Page 90: 2009-02 Oops!

최태리

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…

Page 91: 2009-02 Oops!

최태리

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

Page 92: 2009-02 Oops!

최태리

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.

Page 93: 2009-02 Oops!

최태리

93

Compar ing PHP to ASP.NET i s l ike comparing the Linux kernel to the Windows Platform.

GNU/Linux is the kernel + too lcha in . That toolchain is based on a lot of small interacting programs that can be cha ined to c reate complex behavior.

Windows does the complicated approach.

we say Unix has…

Page 94: 2009-02 Oops!

cohesionvs coupling.

Page 95: 2009-02 Oops!

최태리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…

Page 96: 2009-02 Oops!

최태리

Some of these frameworks are great, but the best are reused entirely (i.e. shrink-wrapped).

and Frameworks failAriadne, 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…

Page 97: 2009-02 Oops!

acyclic dependency

Page 98: 2009-02 Oops!

depend on stability

Page 99: 2009-02 Oops!

최태리

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

Page 100: 2009-02 Oops!

최태리

100

Caveat: I’m going to use that bad “construction” analogy…

The Leaning Tower of Pi sa wa s bu i l t on a shifting foundation. It’s been l ean ing s ince before it was finished.

Sounds like the what happens when you you try to extend someone else’s framework.

Page 101: 2009-02 Oops!

최태리

101

This is a mapping of the PEAR XML package dependencies.

Not ice how weak l y 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_image2svg

XML_NITF

XML_RSS

XML_SaxFilters

XML_Serializer

XML_sql2xml

XML_Statistics

XML_RDDL

Page 102: 2009-02 Oops!

102

roadmap

三二

we now know the precepts by which classes are made

and the parameters by whic they are packaged into classes…

Page 103: 2009-02 Oops!

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!

Page 104: 2009-02 Oops!

what are patterns?

Page 105: 2009-02 Oops!

최태리

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

Page 106: 2009-02 Oops!

최태리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!

Page 107: 2009-02 Oops!

cookie crumbssolve deeply hierarchical navigation

Page 108: 2009-02 Oops!

tabssolve lateral

navigation along a few high level

elements

Page 109: 2009-02 Oops!

tabscan use a million

times over, without ever doing it the same way twice

Page 110: 2009-02 Oops!

최태리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.

Page 111: 2009-02 Oops!

patterns are designed to be linked together

Page 112: 2009-02 Oops!

phpunitpatterndensity

Page 113: 2009-02 Oops!

최태리

patterns三

Page 114: 2009-02 Oops!

최태리

?baddesigntale of the keyfob

Page 115: 2009-02 Oops!

115mybane

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 e r ror occurred on the presentation tier, the user sees one keyfob as four devices. One for each button!

Common

CameraSwitchable

Sensor

HVAC

Page 116: 2009-02 Oops!

최태리

How to make four devices appear as one

?三

Page 117: 2009-02 Oops!

최태리

!a pattern a day keeps the

pink slip away

composite pattern

Page 118: 2009-02 Oops!

최태리

118

Common

Aggregate

A composite pattern adds a subclass that conta ins 1 o r more elements of the base class.

Thus i t 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

Page 119: 2009-02 Oops!

anotherexample三

Page 120: 2009-02 Oops!

최태리

?phpdocdecoupled messaging

Page 121: 2009-02 Oops!

121phpDocu

phpDocumentor is a PEAR l ibra r y /app l i ca t ion 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.

Page 122: 2009-02 Oops!

최태리

How to make a more robust messaging system

?三

Page 123: 2009-02 Oops!

최태리

!allow one object to notify

many (run-time config)

observer pattern

Page 124: 2009-02 Oops!

최태리

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 a l low observer to use subject.

Subject+ attach(&$observer)+ detatch(&$observer)# notify()

Observer+ update()

ConcreteObserver+ update()

ConcreteSubject

0..1*

Page 125: 2009-02 Oops!

최태리

?templatesworking friendly with

designers

Page 126: 2009-02 Oops!

126

shutemplatedotNet’s serverui controls and auto page state are great

but they’re template systems

however PHP IDE != Visual Studio

Page 127: 2009-02 Oops!

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?…

Page 128: 2009-02 Oops!

최태리

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

Page 129: 2009-02 Oops!

129

hatemplatePHP is itself a templating language.

if all web developers are PHP programmers this makes the most sense

however

Page 130: 2009-02 Oops!

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?

Page 131: 2009-02 Oops!

최태리

!doing templates without

o-o

freeenergy

Page 132: 2009-02 Oops!

132

ritemplate1. check for compiled

version.

2. if compiled then include compiled version

3. if not compiled then call routine to compile template

4. use XML!

Page 133: 2009-02 Oops!

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>

Page 134: 2009-02 Oops!

최태리

}conclusion

Page 135: 2009-02 Oops!

최태리

?>questionsAndAnswers

http://homepage.mac.com/tychay/talks/oops