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

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

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

  单件模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
/**
  * 单件模式
  * 确保一个类只有一个实例,并提供一个全局访问点。
  */
class MyClass {
     private static $uniqueInstance ;
     private function __construct() {
  
     }
     public static function getInstance() {
         if (self:: $uniqueInstance == null) {
             self:: $uniqueInstance = new MyClass();
         }
         return self:: $uniqueInstance ;
     }
}
$myClass = MyClass::getInstance();
var_dump( $myClass );
$myClass = MyClass::getInstance();
var_dump( $myClass );
?>

  工厂方法模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<?php
abstract class PizzaStore {
     public function orderPizza( $type ) {
         $pizza = $this ->createPizza( $type );
  
         $pizza ->prepare();
         $pizza ->bake();
         $pizza ->cut();
         $pizza ->box();
         return $pizza ;
     }
  
     public abstract function createPizza( $type );
}
class NYPizzaStore extends PizzaStore {
     public function createPizza( $type ) {
         if ( $type == "cheese" ) {
             return new NYStyleCheesePizza();
         } elseif ( $type == "veggie" ) {
             return new NYStyleVeggiePizza();
         } elseif ( $type == "clam" ) {
             return new NYStyleClamPizza();
         } elseif ( $type == "papperoni" ) {
             return new NYStylePapperoniPizza();
         } else {
             return null;
  
         }
     }
}
class ChicagoPizzaStore extends PizzaStore {
     public function createPizza( $type ) {
         if ( $type == "cheese" ) {
             return new ChicagoStyleCheesePizza();
         } elseif ( $type == "veggie" ) {
             return new ChicagoStyleVeggiePizza();
         } elseif ( $type == "clam" ) {
             return new ChicagoStyleClamPizza();
         } elseif ( $type == "papperoni" ) {
             return new ChicagoStylePapperoniPizza();
         } else {
             return null;
         }
     }
}
abstract class Pizza {
     public $name ;
     public $dough ;
     public $sauce ;
     public $toppings = array ();
  
     public function prepare() {
         echo "Preparing " . $this ->name . "n" ;
         echo "Yossing dough...n" ;
         echo "Adding sauce...n" ;
         echo "Adding toppings: n" ;
         for ( $i = 0; $i < count ( $this ->toppings); $i ++) {
             echo "    " . $this ->toppings[ $i ] . "n" ;
         }
     }
  
     public function bake() {
         echo "Bake for 25 minutes at 350n" ;
     }
  
     public function cut() {
         echo "Cutting the pizza into diagonal slicesn" ;
     }
  
     public function box() {
         echo "Place pizza in official PizzaStore boxn" ;
     }
  
     public function getName() {
         return $this ->name;
     }
}
  
class NYStyleCheesePizza extends Pizza {
     public function __construct() {
         $this ->name = "NY Style Sauce and cheese Pizza" ;
         $this ->dough = "Thin Crust Dough" ;
         $this ->sauce = "Marinara Sauce" ;
  
         $this ->toppings[] = "Grated Reggiano Cheese" ;
     }
}
  
class NYStyleVeggiePizza extends Pizza {
     public function __construct() {
         $this ->name = "NY Style Sauce and veggie Pizza" ;
         $this ->dough = "Thin Crust Dough" ;
         $this ->sauce = "Marinara Sauce" ;
  
         $this ->toppings[] = "Grated Reggiano veggie" ;
     }
}
class NYStyleClamPizza extends Pizza {
     public function __construct() {
         $this ->name = "NY Style Sauce and clam Pizza" ;
         $this ->dough = "Thin Crust Dough" ;
         $this ->sauce = "Marinara Sauce" ;
  
         $this ->toppings[] = "Grated Reggiano clam" ;
     }
}
class NYStylePapperoniPizza extends Pizza {
     public function __construct() {
         $this ->name = "NY Style Sauce and papperoni Pizza" ;
         $this ->dough = "Thin Crust Dough" ;
         $this ->sauce = "Marinara Sauce" ;
  
         $this ->toppings[] = "Grated Reggiano papperoni" ;
     }
}
  
class ChicagoStyleCheesePizza extends Pizza {
     public function __construct() {
         $this ->name = "Chicago Style Deep Dish Cheese Pizza" ;
         $this ->dough = "Extra Thick Crust Dough" ;
         $this ->sauce = "Plum Tomato Sauce" ;
  
         $this ->toppings[] = "Shredded Mozzarella Cheese" ;
     }
  
     public function cut() {
         echo "Cutting the pizza into square slicesn" ;
     }
}
  
$myStore = new NYPizzaStore();
$chicagoStore = new ChicagoPizzaStore();
$pizza = $myStore ->orderPizza( "cheese" );
echo "Ethan ordered a " . $pizza ->getName() . "n" ;
  
$pizza = $chicagoStore ->orderPizza( "cheese" );
echo "Ethan ordered a " . $pizza ->getName() . "n" ;
  
?>

  工厂模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
<?php
abstract class PizzaStore {
     public function orderPizza( $type ) {
         $pizza = $this ->createPizza( $type );
  
         $pizza ->prepare();
         $pizza ->bake();
         $pizza ->cut();
         $pizza ->box();
         return $pizza ;
     }
  
     public abstract function createPizza( $type );
}
class NYPizzaStore extends PizzaStore {
     public function createPizza( $type ) {
         $pizza = null;
         $ingredientFactory = new NYPizzaIngredientFactory();
         if ( $type == "cheese" ) {
             $pizza = new CheesePizza( $ingredientFactory );
             $pizza ->setName( 'New York Style Cheese Pizza' );
         } elseif ( $type == "veggie" ) {
             $pizza = new VeggiePizza( $ingredientFactory );
             $pizza ->setName( 'New York Style Veggie Pizza' );
         } elseif ( $type == "clam" ) {
             $pizza = new ClamPizza( $ingredientFactory );
             $pizza ->setName( 'New York Style Clam Pizza' );
         } elseif ( $type == "papperoni" ) {
             $pizza = new PapperoniPizza( $ingredientFactory );
             $pizza ->setName( 'New York Style Papperoni Pizza' );
         }
         return $pizza ;
     }
}
class ChicagoPizzaStore extends PizzaStore {
     public function createPizza( $type ) {
         if ( $type == "cheese" ) {
             return new ChicagoStyleCheesePizza();
         } elseif ( $type == "veggie" ) {
             return new ChicagoStyleVeggiePizza();
         } elseif ( $type == "clam" ) {
             return new ChicagoStyleClamPizza();
         } elseif ( $type == "papperoni" ) {
             return new ChicagoStylePapperoniPizza();
         } else {
             return null;
         }
     }
}
interface PizzaIngredientFactory {
     public function createDough();
     public function createSauce();
     public function createCheese();
     public function createVeggies();
     public function createPepperoni();
     public function createClam();
}
class NYPizzaIngredientFactory implements PizzaIngredientFactory {
     public function createDough() {
         return new ThinCrustDough();
     }
     public function createSauce() {
         return new MarinaraSauce();
     }
     public function createCheese() {
         return new ReggianoCheese();
     }
     public function createVeggies() {
         $veggies = array (
         new Garlic(),
         new Onion(),
         new Mushroom(),
         new RedPepper(),
         );
         return $veggies ;
     }
     public function createPepperoni() {
         return new SlicedPepperoni();
     }
     public function createClam() {
         return new FreshClams();
     }
}
class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {
     public function createDough() {
         return new ThickCrustDough();
     }
     public function createSauce() {
         return new PlumTomatoSauce();
     }
     public function createCheese() {
         return new Mozzarella();
     }
     public function createVeggies() {
         $veggies = array (
         new BlackOlives(),
         new Spinach(),
         new EggPlant(),
         );
         return $veggies ;
     }
     public function createPepperoni() {
         return new SlicedPepperoni();
     }
     public function createClam() {
         return new FrozenClams();
     }
}
abstract class Pizza {
     public $name ;
     public $dough ;
     public $sauce ;
     public $veggies = array ();
     public $cheese ;
     public $pepperoni ;
     public $clam ;
  
     public abstract function prepare();
  
     public function bake() {
         echo "Bake for 25 minutes at 350n" ;
     }
  
     public function cut() {
         echo "Cutting the pizza into diagonal slicesn" ;
     }
  
     public function box() {
         echo "Place pizza in official PizzaStore boxn" ;
     }
  
     public function getName() {
         return $this ->name;
     }
  
     public function setName( $name ) {
         $this ->name = $name ;
     }
  
     public function __toString() {
  
     }
}
  
class CheesePizza extends Pizza {
     public $ingredientFactory ;
  
     public function __construct(PizzaIngredientFactory $ingredientFactory ) {
         $this ->ingredientFactory = $ingredientFactory ;
     }
  
     public function prepare() {
         echo "Preparing " . $this ->name . "n" ;
         $this ->dough = $this ->ingredientFactory->createDough();
         $this ->sauce = $this ->ingredientFactory->createSauce();
         $this ->cheese = $this ->ingredientFactory->createCheese();
     }
}
  
class ClamPizza extends Pizza {
     public $ingredientFactory ;
  
     public function __construct(PizzaIngredientFactory $ingredientFactory ) {
         $this ->ingredientFactory = $ingredientFactory ;
     }
  
     public function prepare() {
         echo "Preparing " . $this ->name . "n" ;
         $this ->dough = $this ->ingredientFactory->createDough();
         $this ->sauce = $this ->ingredientFactory->createSauce();
         $this ->cheese = $this ->ingredientFactory->createCheese();
         $clam = $this ->ingredientFactory->createClam();
     }
}
  
$nyPizzaStore = new NYPizzaStore();
$nyPizzaStore ->orderPizza( 'cheese' );
?>

  观察者模式

<?php
/**
  * 观察者模式
  * 定义了对象之间的一对多依赖,当一个对象改变状态时,
  * 它的所有依赖者都会收到通知并自动更新。
  */
interface Subject {
     public function registerObserver(Observer $o );
     public function removeObserver(Observer $o );
     public function notifyObservers();
}
interface Observer {
     public function update( $temperature , $humidity , $pressure );
}
interface DisplayElement {
     public function display();
}
class WeatherData implements Subject {
     private $observers = array ();
     private $temperature ;
     private $humidity ;
     private $pressure ;
     public function __construct() {
         $this ->observers = array ();
     }
     public function registerObserver(Observer $o ) {
         $this ->observers[] = $o ;
     }
     public function removeObserver(Observer $o ) {
         if (( $key = array_search ( $o , $this ->observers)) !== false) {
             unset( $this ->observers[ $key ]);
         }
     }
     public function notifyObservers() {
         foreach ( $this ->observers as $observer ) {
             $observer ->update( $this ->temperature, $this ->humidity, $this ->pressure);
         }
     }
     public function measurementsChanged() {
         $this ->notifyObservers();
     }
     public function setMeasurements( $temperature , $humidity , $pressure ) {
         $this ->temperature = $temperature ;
         $this ->humidity = $humidity ;
         $this ->pressure = $pressure ;
         $this ->measurementsChanged();
     }
}
class CurrentConditionsDisplay implements Observer, DisplayElement {
     private $temperature ;
     private $humidity ;
     private $weatherData ;
     public function __construct(Subject $weatherData ) {
         $this ->weatherData = $weatherData ;
         $weatherData ->registerObserver( $this );
     }
     public function update( $temperature , $humidity , $pressure ) {
         $this ->temperature = $temperature ;
         $this ->humidity = $humidity ;
         $this ->display();
     }
     public function display() {
         echo "温度:" . $this ->temperature . "; 湿度:" . $this ->humidity . "%n" ;
     }
}
class StatistionsDisplay implements Observer, DisplayElement {
     private $temperature ;
     private $humidity ;
     private $pressure ;
     private $weatherData ;
     public function __construct(Subject $weatherData ) {
         $this ->weatherData = $weatherData ;
         $weatherData ->registerObserver( $this );
     }
     public function update( $temperature , $humidity , $pressure ) {
         $this ->temperature = $temperature ;
         $this ->humidity = $humidity ;
         $this ->pressure = $pressure ;
         $this ->display();
     }
     public function display() {
         echo "温度:" . $this ->temperature . "; 湿度:" . $this ->humidity . "%; 气压:" . $this ->pressure . "n" ;
     }
}
$weatherData = new WeatherData();
$currentDisplay = new CurrentConditionsDisplay( $weatherData );
$statistionDisplay = new StatistionsDisplay( $weatherData );
$weatherData ->setMeasurements(10, 20, 30);
$weatherData ->removeObserver( $currentDisplay );
$weatherData ->setMeasurements(30, 40, 50);
?>

  命令模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php
  
class Light {
     public function __construct() {
  
     }
  
     public function on() {
         echo "Light Onn" ;
     }
  
     public function off() {
         echo "Light Offn" ;
     }
}
  
interface Command {
     public function execute();
}
  
class LightOnCommand implements Command {
     public $light ;
  
     public function __construct(Light $light ) {
         $this ->light = $light ;
     }
  
     public function execute() {
         $this ->light->on();
     }
}
  
class SimpleRemoteControl {
     public $slot ;
  
     public function __construct() {
  
     }
  
     public function setCommand(Command $command ) {
         $this ->slot = $command ;
     }
  
     public function buttonWasPressed() {
         $this ->slot->execute();
     }
}
  
class RemoteControlTest {
     public static function main() {
         $remote = new SimpleRemoteControl();
         $light = new Light();
         $lightOn = new LightOnCommand( $light );
         $remote ->setCommand( $lightOn );
         $remote ->buttonWasPressed();
     }
}
  
RemoteControlTest::main();
  
?>

  装饰者模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
/**
  * 装饰着模式
  * 动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
  */
abstract class Beverage {
     public $description = "Unknown Beverage" ;
  
     public function getDescription() {
         return $this ->description;
     }
  
     public abstract function cost();
}
  
abstract class CondimentDecorator extends Beverage {
     //JAVA代码里这里是个抽象类,PHP不允许这么做
     public function getDescription() {
         return $this ->description;
     }
}
  
class Espresso extends Beverage {
     public function __construct() {
         $this ->description = "Espresso" ;
     }
  
     public function cost() {
         return 1.99;
     }
}
  
class HouseBlend extends Beverage {
     public function __construct() {
         $this ->description = "HouseBlend" ;
     }
  
     public function cost() {
         return .89;
     }
}
  
class DarkRoast extends Beverage {
     public function __construct() {
         $this ->description = "DarkRoast" ;
     }
  
     public function cost() {
         return .99;
     }
}
  
class Mocha extends CondimentDecorator {
     public $beverage ;
  
     public function __construct(Beverage $beverage ) {
         $this ->beverage = $beverage ;
     }
     public function getDescription() {
         return $this ->beverage->getDescription() . ", Mocha" ;
     }
     public function cost() {
         return .20 + $this ->beverage->cost();
     }
}
  
class Whip extends CondimentDecorator {
     public $beverage ;
  
     public function __construct(Beverage $beverage ) {
         $this ->beverage = $beverage ;
     }
     public function getDescription() {
         return $this ->beverage->getDescription() . ", Whip" ;
     }
     public function cost() {
         return .10 + $this ->beverage->cost();
     }
}
  
class Soy extends CondimentDecorator {
     public $beverage ;
  
     public function __construct(Beverage $beverage ) {
         $this ->beverage = $beverage ;
     }
     public function getDescription() {
         return $this ->beverage->getDescription() . ", Soy" ;
     }
     public function cost() {
         return .15 + $this ->beverage->cost();
     }
}
  
$beverage = new Espresso();
echo $beverage ->getDescription() . "n" ;
$beverage2 = new DarkRoast();
$beverage2 = new Mocha( $beverage2 );
$beverage2 = new Mocha( $beverage2 );
$beverage2 = new Whip( $beverage2 );
echo $beverage2 ->getDescription() . " $" . $beverage2 ->cost() . "n" ;
  
$beverage3 = new HouseBlend();
$beverage3 = new Soy( $beverage3 );
$beverage3 = new Mocha( $beverage3 );
$beverage3 = new Whip( $beverage3 );
echo $beverage3 ->getDescription() . " $" . $beverage3 ->cost() . "n" ;
?>

  状态模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php
  
class GumballMachine {
     const SOLD_OUT = 0;
     const NO_QUARTER = 1;
     const HAS_QUARTER = 2;
     const SOLD = 3;
  
     public $state = self::SOLD_OUT;
     public $count = 0;
  
     public function __construct( $count ) {
         $this -> count = $count ;
         if ( $count > 0) {
             $this ->state = self::NO_QUARTER;
         }
     }
  
     public function insertQuarter() {
         if ( $this ->state == self::HAS_QUARTER) {
             echo "You can't insert another quarter!n" ;
         } else if ( $this ->state == self::NO_QUARTER) {
             $this ->state = self::HAS_QUARTER;
             echo "You inserted a quarter!n" ;
         } else if ( $this ->state == self::SOLD_OUT) {
             echo "You can't insert a quarter, the machine is sold out!n" ;
         } else if ( $this ->state == self::SOLD) {
             echo "Please wait, we're already giving you a gumball!n" ;
         }
     }
}
  
$obj = new GumballMachine(0);
print_r( $obj )
  
?>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值