1. 單例模式用於:

        不重複建立物件,節省記憶體。(PHP很容易卡死的,比如說遞迴20,30 層)比如用於資料庫連線物件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Single {
    private $name;//宣告一個私有的例項變數
    private function __construct(){//宣告私有構造方法為了防止外部程式碼使用new來建立物件。
     
    }
 
    static public $instance;//宣告一個靜態變數(儲存在類中唯一的一個例項)
    static public function getinstance(){//宣告一個getinstance()靜態方法,用於檢測是否有例項物件
        if(!self::$instance) self::$instance new self();
        return self::$instance;
    }
 
    public function setname($n){ $this->name = $n; }
    public function getname(){ return $this->name; }
}

2.工廠模式用於:

        應該TP裡面的M方法建立迷行應該就是這樣,感覺和單例還是很像的。

        工廠模式就是一種類,具有為您建立物件的某些方法,這樣就可以使用工廠類建立物件,而不直接使用new。這樣如果想更改建立的物件型別,只需更改該工廠即可。

1
2
3
4
5
6
7
8
 class Factory {//建立一個基本的工廠類 
     static public function fac($id){//建立一個返回物件例項的靜態方法 
         if(1 == $idreturn new A(); 
         elseif(2==$idreturn new B();
         elseif(3==$idreturn new C(); 
         return new D(); 
 
 }

3.觀察者模式:

        針對一個博主,這是一個介面或者物件,裡面可以註冊觀察者(關注者),然後遍歷關注者,對每個人執行一個方法。例如這個樣子:

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
<?php
    //主題
    class Paper{
        private $_observers array();
 
        //註冊觀察者,誰依賴我,誰是我的粉絲,我有動態,依次推送,都在觀察關注我
        public function register($sub){
            $this->_observers[] = $sub
        }
 
        //外部統一訪問
        public function trigger(){
            if(!empty($this->_observers)){
                foreach($this->_observers as $observer){
                    $observer->update();//統一的方法,依次進行各個觀察者
                }
            }
 
        }
    }
 
    //觀察者實現介面
 
    interface Observerable{
        public function update();
    }
 
    class Subscriber implements Observerable{
        public function update(){
            echo "Callback
"
;
        }
    }
 
    $paper new Paper();
 
    $paper->register(new Subscriber());
    $paper->trigger();

4.策略模式

針對同一個行為,你有不同的方案,就可以寫成策略,就是一個大的演算法集合。再比如你定價有不同的活動,滿200-10,滿400-100等,都是一個小演算法,集合成策略

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
<?php
    interface FlyBehavior{
        //策略介面
        public function fly();
    }
 
    class FlyWithWings implements FlyBehavior{
        //c策略1
        public function fly(){
            echo "Fly with Wings";
        }
    }
 
    class FlyWithNo implements FlyBehavior{
        //c策略2
        public function fly(){
            echo "Fly with No Wings";
        }
    }
 
    class Duck{
        private $_flyBehavior;
        public function performFly(){
            $this->_flyBehavior->fly();
        }
        //這裡引進來策略,可以切換不同的策略
        public function setFlyBehavior(FlyBehavior $behavior){
            $this->_flyBehavior = $behavior;
        }
    }
 
    class RubberDuck extends Duck{
 
    }
 
    $duck new RubberDuck();
    $duck->setFlyBehavior(new FlyWithWings());
    $duck->performFly();
 
    $duck->setFlyBehavior(new FlyWithWings());
    $duck->performFly();

5.裝飾者模式

就是給被裝飾者增加屬性的,之後你就可以取代被裝飾者。其實一個明顯的例子就是穿衣服的順序和方案。因為你有很多的方案可以動態加進去。這樣的話比生成子類好很多,就不用把每個方案都建立物件,然後執行方法。

不恰當的示例如下:

$a = new a(new person());

$a.show();

$b=new b(new person());

$b.show();

$c = new c(new person());

$c.show();

改進的方案如下:首先把a,b,c 寫一個抽象的介面統一起來,然後在面對被裝飾者person()

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
<?php
    //抽象類不能例項化
    abstract class Beverage{
        public $_name;//品類名
        abstract public function Cost();//費用
    }
 
    //被裝飾者,都是給coffee加東西
    class Coffee extends Beverage{
        public function __construct(){
            $this->_name = `Coffee`;//品類名
        }
        public  function Cost(){
            return 1.00;//原味咖啡的底價
        }
    }
 
    //以下三個類是裝飾者相關類
    class CondimentDecorator extends Beverage{
        public function __construct(){
            $this->_name = `Condiment`;
        }
        public function Cost(){
            return 0.1;
        }
    }
 
    class Milk extends CondimentDecorator{
        public $_beverage;//被裝飾者
        public function __construct($beverage){
            $this->_name = `Milk`;//該品種名
            if($beverage instanceof Beverage){
                $this->_beverage = $beverage;
            }else{
                exit(`Failure`);
            }
        }
 
        public function Cost(){
            return $this->_beverage->Cost()+0.2;//底價加上新加的東西
        }
    }
 
    class Sugar extends CondimentDecorator{
        public $_beverage;//被裝飾者
        public function __construct($beverage){
            $this->_name = `Sugar`;//該品種名
            if($beverage instanceof Beverage){
                $this->_beverage = $beverage;
            }else{
                exit(`Failure`);
            }
        }
 
        public function Cost(){
            return $this->_beverage->Cost()+0.2;//底價加上新加的東西
        }
    }
 
    //拿杯咖啡
    $coffee new Coffee();
    //加點牛奶
    $coffee new Milk($coffee);
    //加點糖
    $coffee new Sugar($coffee);
 
    echo "Coffee現在的總價格是".$coffee->Cost();
 
    //總結:
    //1.裝飾者和被裝飾者必須是同一型別,因為裝飾者可以取代它
    //2.當裝飾者和元件組合的時候,就是在加入新的行為