创建型设计模式的PHP实现

1、单例模式(Singleton Pattern)

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
<?php
 
/**
 * 懒汉式
 */
class singleton {
    private static $_instance = null;
 
    private function __construct() {
        // TODO: Initialization Once
    }
 
    public static function getInstance() {
        if (self::$_instance == null) {
            self::$_instance = new singleton();
        }
        return self::$_instance;
    }
 
    // 防止用户克隆实例
    public function __clone() {
        die('Clone is not allowed.' . E_USER_ERROR);
    }
}
 
/**
 * 饿汉式(无法实现)
 * 因PHP不支持类定义时给属性赋予非基本类型的值,如表达式,new 操作等。
 */

2、工厂模式(Factory Pattern)

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
<?php
interface Shape {
    public function draw();
}
 
class Rectangle implements Shape {
    public function draw() {
        echo 'Inside Rectangle::draw() method.' . "\n";
    }
}
 
class Square implements Shape {
    public function draw() {
        echo 'Inside Square::draw() method.' . "\n";
    }
}
 
class Circle implements Shape {
    public function draw() {
        echo 'Inside Circle::draw() method.' . "\n";
    }
}
 
class ShapeFactory {
    public function getShape($shapeType) {
        if ($shapeType) {
            switch (strtoupper($shapeType)) {
                case 'RECTANGLE':
                    return new Rectangle();
                case 'SQUARE':
                    return new Square();
                case 'CIRCLE':
                    return new Circle();
            }
        }
        return null;
    }
}

3、抽象工厂模式(Abstract Factory Pattern)

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
<?php
interface Shape {
    public function draw();
}
 
class Rectangle implements Shape {
    public function draw() {
        echo 'Inside Rectangle::draw() method.' . "\n";
    }
}
 
class Square implements Shape {
    public function draw() {
        echo 'Inside Square::draw() method.' . "\n";
    }
}
 
class Circle implements Shape {
    public function draw() {
        echo 'Inside Circle::draw() method.' . "\n";
    }
}
 
interface Color {
    public function fill();
}
 
class Red implements Color {
    public function fill() {
        echo 'Inside Red::fill() method.' . "\n";
    }
}
 
class Green implements Color {
    public function fill() {
        echo 'Inside Green::fill() method.' . "\n";
    }
}
 
class Blue implements Color {
    public function fill() {
        echo 'Inside Blue::fill() method.' . "\n";
    }
}
 
abstract class AbstractFactory {
    public abstract function getShape($shape);
    public abstract function getColor($color);
}
 
class ShapeFactory extends AbstractFactory {
    public function getShape($shape) {
        if ($shape) {
            switch (strtoupper($shape)) {
                case 'RECTANGLE':
                    return new Rectangle();
                case 'SQUARE':
                    return new Square();
                case 'CIRCLE':
                    return new Circle();
            }
        }
        return null;
    }
 
    public function getColor($color) {
        return null;
    }
}
 
class ColorFactory extends AbstractFactory {
    public function getShape($shape) {
        return null;
    }
 
    public function getColor($color) {
        if ($color) {
            switch (strtoupper($color)) {
                case 'RED':
                    return new Red();
                case 'GREEN':
                    return new Green();
                case 'BLUE':
                    return new Blue();
            }
        }
        return null;
    }
}
 
class FactoryProducer {
    public static function getFactory($choice) {
        if ($choice) {
            switch (strtoupper($choice)) {
                case 'SHAPE':
                    return new ShapeFactory();
                case 'COLOR':
                    return new ColorFactory();
            }
        }
        return null;
    }
}
 
//获取形状工厂
$shapeFactory = FactoryProducer::getFactory('SHAPE');
 
//获取形状为 Circle 的对象
$shape1 = $shapeFactory->getShape('CIRCLE');
 
//调用 Circle 的 draw 方法
$shape1->draw();
 
//获取形状为 Rectangle 的对象
$shape2 = $shapeFactory->getShape('RECTANGLE');
 
//调用 Rectangle 的 draw 方法
$shape2->draw();
 
//获取形状为 Square 的对象
$shape3 = $shapeFactory->getShape('SQUARE');
 
//调用 Square 的 draw 方法
$shape3->draw();
 
//获取颜色工厂
$colorFactory = FactoryProducer::getFactory('COLOR');
 
//获取颜色为 Red 的对象
$color1 = $colorFactory->getColor('RED');
 
//调用 Red 的 fill 方法
$color1->fill();
 
//获取颜色为 Green 的对象
$color2 = $colorFactory->getColor('Green');
 
//调用 Green 的 fill 方法
$color2->fill();
 
//获取颜色为 Blue 的对象
$color3 = $colorFactory->getColor('BLUE');
 
//调用 Blue 的 fill 方法
$color3->fill();

4、建造者模式(Builder Pattern)

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
<?php
 
interface Item {
    public function getName();
    public function getPrice();
    public function packing();
}
 
interface Pack {
    public function pack();
}
 
class Wrapper implements Pack {
    public function pack() {
        return 'Wrapper';
    }
}
 
class Bottle implements Pack {
    public function pack() {
        return 'Bottle';
    }
}
 
abstract class Burger implements Item {
    public function packing() {
        return new Wrapper();
    }
 
    public abstract function getPrice();
}
 
abstract class Drink implements Item {
    public function packing() {
        return new Bottle();
    }
 
    public abstract function getPrice();
}
 
class VegBurger extends Burger {
    public function getName() {
        return 'Veg Burger';
    }
 
    public function getPrice() {
        return 25.0;
    }
}
 
class ChickenBurger extends Burger {
    public function getName() {
        return 'Chicken Burger';
    }
 
    public function getPrice() {
        return 50.5;
    }
}
 
class CokeCola extends Drink {
    public function getName() {
        return 'Coke Cola';
    }
 
    public function getPrice() {
        return 8.0;
    }
}
 
class OrangeTea extends Drink {
    public function getName() {
        return 'Orange Tea';
    }
 
    public function getPrice() {
        return 12.5;
    }
}
 
class Meal {
    private $itemList = [];
 
    public function addItem($item) {
        if ($item instanceof Item) {
            $this->itemList[] = $item;
        } else {
            echo 'error: it is not a item.';
        }
    }
 
    public function getCost() {
        $cost = 0;
        foreach ($this->itemList as $item) {
            $cost += $item->getPrice();
        }
        return $cost;
    }
 
    public function showItems() {
        foreach ($this->itemList as $item) {
            echo 'Item : ' . $item->getName();
            echo ', Packing : ' . $item->packing()->pack();
            echo ', Price : ' . $item->getPrice();
            echo "\n";
        }
    }
}
 
class MealBuilder {
    public function prepareVegMeal() {
        $meal = new Meal();
        $meal->addItem(new VegBurger());
        $meal->addItem(new OrangeTea());
        return $meal;
    }
 
    public function prepareNonVegMeal() {
        $meal = new Meal();
        $meal->addItem(new ChickenBurger());
        $meal->addItem(new CokeCola());
        return $meal;
    }
}
 
$mealBuilder = new MealBuilder();
 
$vegMeal = $mealBuilder->prepareVegMeal();
echo "Veg Meal";
$vegMeal->showItems();
echo "Total Cost: " . $vegMeal->getCost();
 
$nonVegMeal = $mealBuilder->prepareNonVegMeal();
echo "\n\nNon-Veg Meal";
$nonVegMeal->showItems();
echo "Total Cost: " . $nonVegMeal->getCost();

5、原型模式(Prototype Pattern)

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
<?php
 
abstract class Shape {
    private $id;
    protected $type;
 
    abstract function draw();
 
    public function getId() {
        return $this->id;
    }
 
    public function getType() {
        return $this->type;
    }
 
    public function setId($id) {
        $this->id = $id;
    }
 
    public function __clone() {
        // TODO: Deep Copy ...
    }
}
 
class Rectangle extends Shape {
    public function __construct() {
        $this->type = 'Rectangle';
    }
 
    public function draw() {
        echo 'Inside Rectangle::draw() method.' . "\n";
    }
}
 
class Square extends Shape {
    public function __construct() {
        $this->type = 'Square';
    }
 
    public function draw() {
        echo 'Inside Square::draw() method.' . "\n";
    }
}
 
class Circle extends Shape {
    public function __construct() {
        $this->type = 'Circle';
    }
 
    public function draw() {
        echo 'Inside Circle::draw() method.' . "\n";
    }
}
 
class ShapeCache {
    private static $shapeMap = [];
 
    public static function getShape($shapeId) {
        if (isset(self::$shapeMap[$shapeId])) {
            return clone self::$shapeMap[$shapeId];
        }
        return null;
    }
 
    public static function loadCache() {
        $circle = new Circle();
        $circle->setId(1);
        self::$shapeMap[$circle->getId()] = $circle;
 
        $square = new Square();
        $square->setId(2);
        self::$shapeMap[$square->getId()] = $square;
 
        $rectangle = new Rectangle();
        $rectangle->setId(3);
        self::$shapeMap[$rectangle->getId()] = $rectangle;
    }
}
 
ShapeCache::loadCache();
 
$clonedShape = ShapeCache::getShape(1);
echo 'Shape : ' . $clonedShape->getType() . "\n";
 
$clonedShape = ShapeCache::getShape(2);
echo 'Shape : ' . $clonedShape->getType() . "\n";
 
$clonedShape = ShapeCache::getShape(3);
echo 'Shape : ' . $clonedShape->getType() . "\n";

发表评论

电子邮件地址不会被公开。 必填项已用*标注