PHP設計模式之工廠模式和原型模式

科技小能手發表於2017-11-12

這兩個模式都是針對物件建立和複用的,只是一種設計風格,在建立物件的,隨時都可以改進現有的程式碼。畢竟老程式碼很多地方不容易更改了,所以這兩個模式一般適合新加進去,比較容易建立物件或者使用新物件


再者就是。。。算了


我想說的就是JS,把原型做的爐火純青,我一直很痴迷,很多原型都深深的嵌入到語言的核心。


推薦那本書<你不知道的JS>


上程式碼

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
    interface Prototype{
        public function shallowCopy();
        public function deepCopy();
    }
 
    class ConcretePrototype implements Prototype{
        private $_name;
        public function __construct($name){
            $this->_name = $name;
        }
 
        public function setName($name){
            $this->_name = $name;
        }
 
        public function shallowCopy(){
            //在php語言中,用簡單的賦值語句是不能滿足這種需求的。要滿足這種需求雖然有很多途徑,但實現clone()方法是其中最簡單,也是最高效的手段。
            //如果定義了__clone()方法,則新建立的物件(複製生成的物件)中的__clone()方法會被呼叫, 可用於修改屬性的值
            //你要先new物件才能clone,一個是例項化,一個是克隆
            //物件的複製是通過關鍵字 clone 來實現的。用 clone 克隆出來的物件與原物件沒有任何關係,它是把原來的物件從當前的位置重新複製了一份,也就是相當於在記憶體中新開闢了一塊空間
            return clone $this;
        }
 
        public function deepCopy(){
            //序列化深拷貝:利用序列化來做深拷貝,把物件寫到流裡的過程是序列化的過程,這一過程稱為“冷凍”或“醃鹹菜”,反序列化物件的過程叫做“解凍”或“回鮮”。這種深複製比較簡單
            //當陣列值包含如雙引號、單引號或冒號等字元時,它們被反序列化後,可能會出現問題。為了克服這個問題,一個巧妙的技巧是使用base64_encode和base64_decode。
            //但是base64編碼將增加字串的長度。為了克服這個問題,可以和gzcompress一起使用。 //base64_encode(gzcompress(serialize($obj)));序列化
            //unserialize(gzuncompress(base64_decode($txt)));反序列化
 
            $serialize_obj = serialize($this);
            $clone_obj = unserialize($serialize_obj);
            return $clone_obj;
        }
        public function getName(){
            return $this->_name;
        }
    }
 
 
//上面的原型基本上就寫完了
 
    class Demo{
        public $string;
    }
    class UsePrototype{
        public function shallow(){
            $demo new Demo();
            $demo->string = "susan";
            //新建
            $object_shallow_first new ConcretePrototype($demo);
            //淺複製
            $object_shallow_second $object_shallow_first->shallowCopy();
            //之下程式碼可以刪除
            echo `新物件:<br/>`;
            var_dump($object_shallow_first->getName());
            echo `淺複製的物件<br/>`;
            var_dump($object_shallow_second->getName());
            echo `<br/>`;
 
            $demo->string = "jack";
         
            echo `我改變新建的物件屬性:<br/>`;
            var_dump($object_shallow_first->getName());
            echo `淺複製是同一塊記憶體,受影響<br/>`;
            var_dump($object_shallow_second->getName());
            echo `<br/>`;
        }
 
        public function deep(){
            //新建物件,建構函式沒引數就不用帶括號
            $demo new Demo;
            $demo->string = "Siri";
            //新建
            $object_shallow_first new ConcretePrototype($demo);
            //淺複製
            $object_shallow_second $object_shallow_first->deepCopy();
            //之下程式碼可以刪除
            echo `新物件:<br/>`;
            var_dump($object_shallow_first->getName());
            echo `深複製的物件<br/>`;
            var_dump($object_shallow_second->getName());
            echo `<br/>`;
 
            $demo->string = "jack";
         
            echo `我改變新建的物件屬性:<br/>`;
            var_dump($object_shallow_first->getName());
            echo `深複製是完全新的物件,不受影響<br/>`;
            var_dump($object_shallow_second->getName());
            echo `<br/>`;
        }
    }
 
    //呼叫
 
    $up new UsePrototype;
    $up->shallow();
    echo `<hr>`;
    $up->deep();
    //原型模式的主要思想是基於現有的物件克隆一個新的物件出來,一般是用物件內部提供的克隆方法,通過該方法返回一個物件的副本,這種建立物件的方式,相比我們之前說的幾類建立型模式還是有區別的,之前的講述的工廠方法模式與抽象工廠都是通過工廠封裝具體的 new 操作的過程,返回一個新的物件,有的時候我們通過這樣的建立工廠建立物件不值得,特別是以下的幾個場景,可能使用原型模式更簡單、效率更高:
 
    //如果說我們的物件型別不是剛開始就能確定,而是在執行時確定的話,那麼我們通過這個型別的物件克隆出一個新的型別更容易。
    //有的時候我們可能在實際的專案中需要一個物件在某個狀態下的副本,這個前提很重要,這點怎麼理解呢,例如有的時候我們需要對比一個物件經過處理後的狀態和處理前的狀態是否發生過改變,可能我們就需要在執行某段處理之前,克隆這個物件此時狀態的副本,然後等執行後的狀態進行相應的對比,這樣的應用在專案中也是經常會出現的。
    //當我們處理的物件比較簡單,並且物件之間的區別很小,可能只是很固定的幾個屬性不同的時候,使用原型模式更合適。
 
 
?>



願法界眾生,皆得安樂

本文轉自 jackdongting 51CTO部落格,原文連結:http://blog.51cto.com/10725691/1954805


相關文章