首页 » 随笔 » 阅读文章

《Head First 设计模式》代码之PHP版

2010-05-25 09:51 3408 0 发表评论

  《Head First 设计模式》是本不错的讲解设计模式的书,不像F4写的那么枯燥,应该算是比较容易理解的好书。书中的例子都比较浅显易懂,不过由于是外国佬写的,所以例子的习惯不是很附合中国特色,可能偶尔看起来有些别扭,还有语言习惯也不是中国风。当然��看过这本书之后,你才能深刻理解设计模式到底能为你解决哪些问题,不能为你解决哪些问题(比如不能代替你的编码)。
  我将书中部分代码改成PHP,看下代码再配合概念应该是比较容易理解了。
  策略模式

01 <?php
02 /**
03  * 策略模式
04  * 定义了算法族,分别封装起来,让它们之间可以互相替换,
05  * 此模式让算法的变化独立于使用算法的客户。
06  */
07 //飞行行为接口
08 interface FlyBehavior {
09     public function fly();
10 }
11 //呱呱叫行为接口
12 interface QuackBehavior {
13     public function quack();
14 }
15 //翅膀飞行
16 class FlyWithWings implements FlyBehavior {
17     public function fly() {
18         echo "I'm flying!!\n";
19     }
20 }
21 //不会飞
22 class FlyNoWay implements FlyBehavior {
23     public function fly() {
24         echo "I can't fly!\n";
25     }
26 }
27 class FlyRocketPowered implements FlyBehavior {
28     public function fly() {
29         echo "I'm flying with a rocket!\n";
30     }
31 }
32 class Qquack implements QuackBehavior {
33     public function quack() {
34         echo "Quack\n";
35     }
36 }
37 class Squeak implements QuackBehavior {
38     public function quack() {
39         echo "Squeak\n";
40     }
41 }
42 class MuteQuack implements QuackBehavior {
43     public function quack() {
44         echo "<< Silence >>\n";
45     }
46 }
47 abstract class Duck {
48     protected $quack_obj;
49     protected $fly_obj;
50     public abstract function display();
51   
52     public function performQuack() {
53         $this->quack_obj->quack();
54     }
55     public function performFly() {
56         $this->fly_obj->fly();
57     }
58     public function swim() {
59         echo "All ducks float, even decoys!\n";
60     }
61     public function setFlyBehavior(FlyBehavior $fb) {
62         $this->fly_obj = $fb;
63     }
64     public function setQuackBehavior(QuackBehavior $qb) {
65         $this->quack_obj = $qb;
66     }
67 }
68   
69 class ModelDuck extends Duck {
70     public function __construct() {
71         $this->fly_obj = new FlyNoWay();
72         $this->quack_obj = new MuteQuack();
73     }
74     public function display() {
75         echo "I'm a model duck!\n";
76     }
77 }
78   
79 $model = new ModelDuck();
80 $model->performFly();
81 $model->performQuack();
82 //提供新的能力
83 $model->setFlyBehavior(new FlyRocketPowered());
84 $model->setQuackBehavior(new Squeak());
85 $model->performFly();
86 $model->performQuack();
87   
88 ?>

  单件模式

01 <?php
02 /**
03  * 单件模式
04  * 确保一个类只有一个实例,并提供一个全局访问点。
05  */
06 class MyClass {
07     private static $uniqueInstance;
08     private function __construct() {
09   
10     }
11     public static function getInstance() {
12         if (self::$uniqueInstance == null) {
13             self::$uniqueInstance = new MyClass();
14         }
15         return self::$uniqueInstance;
16     }
17 }
18 $myClass = MyClass::getInstance();
19 var_dump($myClass);
20 $myClass = MyClass::getInstance();
21 var_dump($myClass);
22 ?>

  工厂方法模式

001 <?php
002 abstract class PizzaStore {
003     public function orderPizza($type) {
004         $pizza = $this->createPizza($type);
005   
006         $pizza->prepare();
007         $pizza->bake();
008         $pizza->cut();
009         $pizza->box();
010         return $pizza;
011     }
012   
013     public abstract function createPizza($type);
014 }
015 class NYPizzaStore extends PizzaStore {
016     public function createPizza($type) {
017         if ($type == "cheese") {
018             return new NYStyleCheesePizza();
019         } elseif ($type == "veggie") {
020             return new NYStyleVeggiePizza();
021         } elseif ($type == "clam") {
022             return new NYStyleClamPizza();
023         } elseif ($type == "papperoni") {
024             return new NYStylePapperoniPizza();
025         } else {
026             return null;
027   
028         }
029     }
030 }
031 class ChicagoPizzaStore extends PizzaStore {
032     public function createPizza($type) {
033         if ($type == "cheese") {
034             return new ChicagoStyleCheesePizza();
035         } elseif ($type == "veggie") {
036             return new ChicagoStyleVeggiePizza();
037         } elseif ($type == "clam") {
038             return new ChicagoStyleClamPizza();
039         } elseif ($type == "papperoni") {
040             return new ChicagoStylePapperoniPizza();
041         } else {
042             return null;
043         }
044     }
045 }
046 abstract class Pizza {
047     public $name;
048     public $dough;
049     public $sauce;
050     public $toppings = array();
051   
052     public function prepare() {
053         echo "Preparing " . $this->name . "\n";
054         echo "Yossing dough...\n";
055         echo "Adding sauce...\n";
056         echo "Adding toppings: \n";
057         for ($i = 0; $i < count($this->toppings); $i++) {
058             echo "    " . $this->toppings[$i] . "\n";
059         }
060     }
061   
062     public function bake() {
063         echo "Bake for 25 minutes at 350\n";
064     }
065   
066     public function cut() {
067         echo "Cutting the pizza into diagonal slices\n";
068     }
069   
070     public function box() {
071         echo "Place pizza in official PizzaStore box\n";
072     }
073   
074     public function getName() {
075         return $this->name;
076     }
077 }
078   
079 class NYStyleCheesePizza extends Pizza {
080     public function __construct() {
081         $this->name = "NY Style Sauce and cheese Pizza";
082         $this->dough = "Thin Crust Dough";
083         $this->sauce = "Marinara Sauce";
084   
085         $this->toppings[] = "Grated Reggiano Cheese";
086     }
087 }
088   
089 class NYStyleVeggiePizza extends Pizza {
090     public function __construct() {
091         $this->name = "NY Style Sauce and veggie Pizza";
092         $this->dough = "Thin Crust Dough";
093         $this->sauce = "Marinara Sauce";
094   
095         $this->toppings[] = "Grated Reggiano veggie";
096     }
097 }
098 class NYStyleClamPizza extends Pizza {
099     public function __construct() {
100         $this->name = "NY Style Sauce and clam Pizza";
101         $this->dough = "Thin Crust Dough";
102         $this->sauce = "Marinara Sauce";
103   
104         $this->toppings[] = "Grated Reggiano clam";
105     }
106 }
107 class NYStylePapperoniPizza extends Pizza {
108     public function __construct() {
109         $this->name = "NY Style Sauce and papperoni Pizza";
110         $this->dough = "Thin Crust Dough";
111         $this->sauce = "Marinara Sauce";
112   
113         $this->toppings[] = "Grated Reggiano papperoni";
114     }
115 }
116   
117 class ChicagoStyleCheesePizza extends Pizza {
118     public function __construct() {
119         $this->name = "Chicago Style Deep Dish Cheese Pizza";
120         $this->dough = "Extra Thick Crust Dough";
121         $this->sauce = "Plum Tomato Sauce";
122   
123         $this->toppings[] = "Shredded Mozzarella Cheese";
124     }
125   
126     public function cut() {
127         echo "Cutting the pizza into square slices\n";
128     }
129 }
130   
131 $myStore = new NYPizzaStore();
132 $chicagoStore = new ChicagoPizzaStore();
133 $pizza = $myStore->orderPizza("cheese");
134 echo "Ethan ordered a " . $pizza->getName() . "\n";
135   
136 $pizza = $chicagoStore->orderPizza("cheese");
137 echo "Ethan ordered a " . $pizza->getName() . "\n";
138   
139 ?>

  工厂模式

001 <?php
002 abstract class PizzaStore {
003     public function orderPizza($type) {
004         $pizza = $this->createPizza($type);
005   
006         $pizza->prepare();
007         $pizza->bake();
008         $pizza->cut();
009         $pizza->box();
010         return $pizza;
011     }
012   
013     public abstract function createPizza($type);
014 }
015 class NYPizzaStore extends PizzaStore {
016     public function createPizza($type) {
017         $pizza = null;
018         $ingredientFactory = new NYPizzaIngredientFactory();
019         if ($type == "cheese") {
020             $pizza = new CheesePizza($ingredientFactory);
021             $pizza->setName('New York Style Cheese Pizza');
022         } elseif ($type == "veggie") {
023             $pizza = new VeggiePizza($ingredientFactory);
024             $pizza->setName('New York Style Veggie Pizza');
025         } elseif ($type == "clam") {
026             $pizza = new ClamPizza($ingredientFactory);
027             $pizza->setName('New York Style Clam Pizza');
028         } elseif ($type == "papperoni") {
029             $pizza = new PapperoniPizza($ingredientFactory);
030             $pizza->setName('New York Style Papperoni Pizza');
031         }
032         return $pizza;
033     }
034 }
035 class ChicagoPizzaStore extends PizzaStore {
036     public function createPizza($type) {
037         if ($type == "cheese") {
038             return new ChicagoStyleCheesePizza();
039         } elseif ($type == "veggie") {
040             return new ChicagoStyleVeggiePizza();
041         } elseif ($type == "clam") {
042             return new ChicagoStyleClamPizza();
043         } elseif ($type == "papperoni") {
044             return new ChicagoStylePapperoniPizza();
045         } else {
046             return null;
047         }
048     }
049 }
050 interface PizzaIngredientFactory {
051     public function createDough();
052     public function createSauce();
053     public function createCheese();
054     public function createVeggies();
055     public function createPepperoni();
056     public function createClam();
057 }
058 class NYPizzaIngredientFactory implements PizzaIngredientFactory {
059     public function createDough() {
060         return new ThinCrustDough();
061     }
062     public function createSauce() {
063         return new MarinaraSauce();
064     }
065     public function createCheese() {
066         return new ReggianoCheese();
067     }
068     public function createVeggies() {
069         $veggies = array(
070         new Garlic(),
071         new Onion(),
072         new Mushroom(),
073         new RedPepper(),
074         );
075         return $veggies;
076     }
077     public function createPepperoni() {
078         return new SlicedPepperoni();
079     }
080     public function createClam() {
081         return new FreshClams();
082     }
083 }
084 class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {
085     public function createDough() {
086         return new ThickCrustDough();
087     }
088     public function createSauce() {
089         return new PlumTomatoSauce();
090     }
091     public function createCheese() {
092         return new Mozzarella();
093     }
094     public function createVeggies() {
095         $veggies = array(
096         new BlackOlives(),
097         new Spinach(),
098         new EggPlant(),
099         );
100         return $veggies;
101     }
102     public function createPepperoni() {
103         return new SlicedPepperoni();
104     }
105     public function createClam() {
106         return new FrozenClams();
107     }
108 }
109 abstract class Pizza {
110     public $name;
111     public $dough;
112     public $sauce;
113     public $veggies = array();
114     public $cheese;
115     public $pepperoni;
116     public $clam;
117   
118     public abstract function prepare();
119   
120     public function bake() {
121         echo "Bake for 25 minutes at 350\n";
122     }
123   
124     public function cut() {
125         echo "Cutting the pizza into diagonal slices\n";
126     }
127   
128     public function box() {
129         echo "Place pizza in official PizzaStore box\n";
130     }
131   
132     public function getName() {
133         return $this->name;
134     }
135   
136     public function setName($name) {
137         $this->name = $name;
138     }
139   
140     public function __toString() {
141   
142     }
143 }
144   
145 class CheesePizza extends Pizza {
146     public $ingredientFactory;
147   
148     public function __construct(PizzaIngredientFactory $ingredientFactory) {
149         $this->ingredientFactory = $ingredientFactory;
150     }
151   
152     public function prepare() {
153         echo "Preparing " . $this->name . "\n";
154         $this->dough = $this->ingredientFactory->createDough();
155         $this->sauce = $this->ingredientFactory->createSauce();
156         $this->cheese = $this->ingredientFactory->createCheese();
157     }
158 }
159   
160 class ClamPizza extends Pizza {
161     public $ingredientFactory;
162   
163     public function __construct(PizzaIngredientFactory $ingredientFactory) {
164         $this->ingredientFactory = $ingredientFactory;
165     }
166   
167     public function prepare() {
168         echo "Preparing " . $this->name . "\n";
169         $this->dough = $this->ingredientFactory->createDough();
170         $this->sauce = $this->ingredientFactory->createSauce();
171         $this->cheese = $this->ingredientFactory->createCheese();
172         $clam = $this->ingredientFactory->createClam();
173     }
174 }
175   
176 $nyPizzaStore = new NYPizzaStore();
177 $nyPizzaStore->orderPizza('cheese');
178 ?>

  观察者模式

01 <?php
02 /**
03  * 观察者模式
04  * 定义了对象之间的一对多依赖,当一个对象改变状态时,
05  * 它的所有依赖者都会收到通知并自动更新。
06  */
07 interface Subject {
08     public function registerObserver(Observer $o);
09     public function removeObserver(Observer $o);
10     public function notifyObservers();
11 }
12 interface Observer {
13     public function update($temperature, $humidity, $pressure);
14 }
15 interface DisplayElement {
16     public function display();
17 }
18 class WeatherData implements Subject {
19     private $observers = array();
20     private $temperature;
21     private $humidity;
22     private $pressure;
23     public function __construct() {
24         $this->observers = array();
25     }
26     public function registerObserver(Observer $o) {
27         $this->observers[] = $o;
28     }
29     public function removeObserver(Observer $o) {
30         if (($key = array_search($o, $this->observers)) !== false) {
31             unset($this->observers[$key]);
32         }
33     }
34     public function notifyObservers() {
35         foreach ($this->observers as $observer) {
36             $observer->update($this->temperature, $this->humidity, $this->pressure);
37         }
38     }
39     public function measurementsChanged() {
40         $this->notifyObservers();
41     }
42     public function setMeasurements($temperature, $humidity, $pressure) {
43         $this->temperature = $temperature;
44         $this->humidity = $humidity;
45         $this->pressure = $pressure;
46         $this->measurementsChanged();
47     }
48 }
49 class CurrentConditionsDisplay implements Observer, DisplayElement {
50     private $temperature;
51     private $humidity;
52     private $weatherData;
53     public function __construct(Subject $weatherData) {
54         $this->weatherData = $weatherData;
55         $weatherData->registerObserver($this);
56     }
57     public function update($temperature, $humidity, $pressure) {
58         $this->temperature = $temperature;
59         $this->humidity = $humidity;
60         $this->display();
61     }
62     public function display() {
63         echo "温度:" . $this->temperature . "; 湿度:" . $this->humidity . "%\n";
64     }
65 }
66 class StatistionsDisplay implements Observer, DisplayElement {
67     private $temperature;
68     private $humidity;
69     private $pressure;
70     private $weatherData;
71     public function __construct(Subject $weatherData) {
72         $this->weatherData = $weatherData;
73         $weatherData->registerObserver($this);
74     }
75     public function update($temperature, $humidity, $pressure) {
76         $this->temperature = $temperature;
77         $this->humidity = $humidity;
78         $this->pressure = $pressure;
79         $this->display();
80     }
81     public function display() {
82         echo "温度:" . $this->temperature . "; 湿度:" . $this->humidity . "%; 气压:" . $this->pressure . "\n";
83     }
84 }
85 $weatherData = new WeatherData();
86 $currentDisplay = new CurrentConditionsDisplay($weatherData);
87 $statistionDisplay = new StatistionsDisplay($weatherData);
88 $weatherData->setMeasurements(10, 20, 30);
89 $weatherData->removeObserver($currentDisplay);
90 $weatherData->setMeasurements(30, 40, 50);
91 ?>

  命令模式

01 <?php
02   
03 class Light {
04     public function __construct() {
05   
06     }
07   
08     public function on() {
09         echo "Light On\n";
10     }
11   
12     public function off() {
13         echo "Light Off\n";
14     }
15 }
16   
17 interface Command {
18     public function execute();
19 }
20   
21 class LightOnCommand implements Command {
22     public $light;
23   
24     public function __construct(Light $light) {
25         $this->light = $light;
26     }
27   
28     public function execute() {
29         $this->light->on();
30     }
31 }
32   
33 class SimpleRemoteControl {
34     public $slot;
35   
36     public function __construct() {
37   
38     }
39   
40     public function setCommand(Command $command) {
41         $this->slot = $command;
42     }
43   
44     public function buttonWasPressed() {
45         $this->slot->execute();
46     }
47 }
48   
49 class RemoteControlTest {
50     public static function main() {
51         $remote = new SimpleRemoteControl();
52         $light = new Light();
53         $lightOn = new LightOnCommand($light);
54         $remote->setCommand($lightOn);
55         $remote->buttonWasPressed();
56     }
57 }
58   
59 RemoteControlTest::main();
60   
61 ?>

  装饰者模式

001 <?php
002 /**
003  * 装饰着模式
004  * 动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
005  */
006 abstract class Beverage {
007     public $description = "Unknown Beverage";
008   
009     public function getDescription() {
010         return $this->description;
011     }
012   
013     public abstract function cost();
014 }
015   
016 abstract class CondimentDecorator extends Beverage {
017     //JAVA代码里这里是个抽象类,PHP不允许这么做
018     public function getDescription() {
019         return $this->description;
020     }
021 }
022   
023 class Espresso extends Beverage {
024     public function __construct() {
025         $this->description = "Espresso";
026     }
027   
028     public function cost() {
029         return 1.99;
030     }
031 }
032   
033 class HouseBlend extends Beverage {
034     public function __construct() {
035         $this->description = "HouseBlend";
036     }
037   
038     public function cost() {
039         return .89;
040     }
041 }
042   
043 class DarkRoast extends Beverage {
044     public function __construct() {
045         $this->description = "DarkRoast";
046     }
047   
048     public function cost() {
049         return .99;
050     }
051 }
052   
053 class Mocha extends CondimentDecorator {
054     public $beverage;
055   
056     public function __construct(Beverage $beverage) {
057         $this->beverage = $beverage;
058     }
059     public function getDescription() {
060         return $this->beverage->getDescription() . ", Mocha";
061     }
062     public function cost() {
063         return .20 + $this->beverage->cost();
064     }
065 }
066   
067 class Whip extends CondimentDecorator {
068     public $beverage;
069   
070     public function __construct(Beverage $beverage) {
071         $this->beverage = $beverage;
072     }
073     public function getDescription() {
074         return $this->beverage->getDescription() . ", Whip";
075     }
076     public function cost() {
077         return .10 + $this->beverage->cost();
078     }
079 }
080   
081 class Soy extends CondimentDecorator {
082     public $beverage;
083   
084     public function __construct(Beverage $beverage) {
085         $this->beverage = $beverage;
086     }
087     public function getDescription() {
088         return $this->beverage->getDescription() . ", Soy";
089     }
090     public function cost() {
091         return .15 + $this->beverage->cost();
092     }
093 }
094   
095 $beverage = new Espresso();
096 echo $beverage->getDescription() . "\n";
097 $beverage2 = new DarkRoast();
098 $beverage2 = new Mocha($beverage2);
099 $beverage2 = new Mocha($beverage2);
100 $beverage2 = new Whip($beverage2);
101 echo $beverage2->getDescription() . " $" . $beverage2->cost() . "\n";
102   
103 $beverage3 = new HouseBlend();
104 $beverage3 = new Soy($beverage3);
105 $beverage3 = new Mocha($beverage3);
106 $beverage3 = new Whip($beverage3);
107 echo $beverage3->getDescription() . " $" . $beverage3->cost() . "\n";
108 ?>

  状态模式

01 <?php
02   
03 class GumballMachine {
04     const SOLD_OUT = 0;
05     const NO_QUARTER = 1;
06     const HAS_QUARTER = 2;
07     const SOLD = 3;
08   
09     public $state = self::SOLD_OUT;
10     public $count = 0;
11   
12     public function __construct($count) {
13         $this->count = $count;
14         if ($count > 0) {
15             $this->state = self::NO_QUARTER;
16         }
17     }
18   
19     public function insertQuarter() {
20         if ($this->state == self::HAS_QUARTER) {
21             echo "You can't insert another quarter!\n";
22         } else if ($this->state == self::NO_QUARTER) {
23             $this->state = self::HAS_QUARTER;
24             echo "You inserted a quarter!\n";
25         } else if ($this->state == self::SOLD_OUT) {
26             echo "You can't insert a quarter, the machine is sold out!\n";
27         } else if ($this->state == self::SOLD) {
28             echo "Please wait, we're already giving you a gumball!\n";
29         }
30     }
31 }
32   
33 $obj = new GumballMachine(0);
34 print_r($obj)
35   
36 ?>
本文地址:http://www.jwzzsw.com/archives/13.html

文章作者:思悟
版权所有 © 转载时请以链接形式注明作者和原始出处!

评论 共0条 (RSS 2.0) 发表评论

  1. 暂无评论,快抢沙发吧。

发表评论

联系我 Contact Me

回到页首