** 創(chuàng)建型設(shè)計(jì)模式 **:
- 單例模式(Singleton Pattern)
- 工廠方法模式(Factor Pattern)
- 抽象工廠模式( Abstract Factor Pattern)
- 建造者模式(Builder Pattern)
- 原型模式(Prototype Pattern)
抽象工廠模式就好比工廠方法模式的升級(jí)版幻赚,所以本文把工廠方法模式和抽象工廠模式混在一起講了
一.單例模式(Singleton Pattern)
單例模式(Singleton Pattern):顧名思義苹熏,就是只有一個(gè)實(shí)例。作為對(duì)象的創(chuàng)建模式,單例模式確保某一個(gè)類只有一個(gè)實(shí)例光督,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例掩幢。
(一)為什么要使用PHP單例模式
1已烤,php的應(yīng)用主要在于數(shù)據(jù)庫應(yīng)用, 一個(gè)應(yīng)用中會(huì)存在大量的數(shù)據(jù)庫操作, 在使用面向?qū)ο蟮姆绞介_發(fā)時(shí), 如果使用單例模式,
則可以避免大量的new 操作消耗的資源,還可以減少數(shù)據(jù)庫連接這樣就不容易出現(xiàn) too many connections情況磁玉。
2,如果系統(tǒng)中需要有一個(gè)類來全局控制某些配置信息, 那么使用單例模式可以很方便的實(shí)現(xiàn). 這個(gè)可以參看zend Framework的FrontController部分中鼠。
3可婶,在一次頁面請(qǐng)求中, 便于進(jìn)行調(diào)試, 因?yàn)樗械拇a(例如數(shù)據(jù)庫操作類db)都集中在一個(gè)類中, 我們可以在類中設(shè)置鉤子, 輸出日志,從而避免到處var_dump, echo
(二)單例模式結(jié)構(gòu)圖
(三)單例模式的實(shí)現(xiàn)
1援雇,私有化一個(gè)屬性用于存放唯一的一個(gè)實(shí)例
2矛渴,私有化構(gòu)造方法,私有化克隆方法惫搏,用來創(chuàng)建并只允許創(chuàng)建一個(gè)實(shí)例
3具温,公有化靜態(tài)方法,用于向系統(tǒng)提供這個(gè)實(shí)例
(四)代碼實(shí)現(xiàn)
class Singleton{
//存放實(shí)例
private static $_instance = null;
//私有化構(gòu)造方法筐赔、
private function __construct(){
echo "單例模式的實(shí)例被構(gòu)造了";
}
//私有化克隆方法
private function __clone(){
}
//公有化獲取實(shí)例方法
public static function getInstance(){
if (!(self::$_instance instanceof Singleton)){
self::$_instance = new Singleton();
}
return self::$_instance;
}
}
$singleton=Singleton::getInstance();
優(yōu)點(diǎn):因?yàn)殪o態(tài)方法可以在全局范圍內(nèi)被訪問铣猩,當(dāng)我們需要一個(gè)單例模式的對(duì)象時(shí),只需調(diào)用getInstance方法茴丰,獲取先前實(shí)例化的對(duì)象达皿,無需重新實(shí)例化。
(五)使用Trait關(guān)鍵字實(shí)現(xiàn)類似于繼承單例類的功能
Trait
是PHP5.4后加入到特性贿肩,有些書說是為了實(shí)現(xiàn)類似C++多重繼承的功能峦椰。Trait定義的代碼結(jié)構(gòu)和類很相似。又有點(diǎn)像實(shí)現(xiàn)邏輯代碼的接口汰规。當(dāng)使用use
的時(shí)候汤功,Trait的代碼就好像拷貝到use所在的位置取代use。從這個(gè)角度來看溜哮,更像C的宏定義
滔金。
Trait Singleton{
//存放實(shí)例
private static $_instance = null;
//私有化克隆方法
private function __clone(){
}
//公有化獲取實(shí)例方法
public static function getInstance(){
$class = __CLASS__;
if (!(self::$_instance instanceof $class)){
self::$_instance = new $class();
}
return self::$_instance;
}
}
class DB {
private function __construct(){
echo __CLASS__.PHP_EOL;
}
}
class DBhandle extends DB {
use Singleton;
private function __construct(){
echo "單例模式的實(shí)例被構(gòu)造了";
}
}
$handle=DBhandle::getInstance();
//注意若父類方法為public,則子類只能為pubic茬射,
//若父類為private鹦蠕,子類為public 冒签,protected在抛,private都可以。
補(bǔ)充萧恕,大多數(shù)書籍介紹單例模式刚梭,都會(huì)講三私一公肠阱,公優(yōu)化靜態(tài)方法作為提供對(duì)象的接口,私有屬性用于存放唯一一個(gè)單例對(duì)象朴读。私有化構(gòu)造方法屹徘,私有化克隆方法保證只存在一個(gè)單例。
但實(shí)際上衅金,雖然我們無法通過new
關(guān)鍵字和clone
出一個(gè)新的對(duì)象噪伊,但我們?nèi)粝氲玫揭粋€(gè)新對(duì)象。還是有辦法的氮唯,那就是通過序列化和反序列化
得到一個(gè)對(duì)象鉴吹。私有化__sleep()
和__wakeup()
方法依然無法阻止通過這種方法得到一個(gè)新對(duì)象〕土穑或許真得要阻止豆励,你只能去__wakeup添加刪除一個(gè)實(shí)例的代碼,保證反序列化增加一個(gè)對(duì)象瞒渠,你就刪除一個(gè)良蒸。不過這樣貌似有點(diǎn)怪異。
單例模式也細(xì)分為懶漢模式
和餓漢模式
伍玖,感興趣的朋友可以去了解一下嫩痰。上面的代碼實(shí)現(xiàn)是懶漢模式
二、工廠模式(Factor Pattern)與抽象工廠模式( Abstract Factor Pattern)
工廠模式(Factor Pattern)窍箍,就是負(fù)責(zé)生成其他對(duì)象的類或方法始赎,也叫工廠方法模式
抽象工廠模式( Abstract Factor Pattern),可簡單理解為工廠模式的升級(jí)版
(一)為什么需要工廠模式
1仔燕,工廠模式可以將對(duì)象的生產(chǎn)從直接new 一個(gè)對(duì)象造垛,改成通過調(diào)用一個(gè)工廠方法生產(chǎn)。這樣的封裝晰搀,代碼若需修改new的對(duì)象時(shí)五辽,不需修改多處new語句,只需更改生產(chǎn)對(duì)象方法外恕。
2杆逗,若所需實(shí)例化的對(duì)象可選擇來自不同的類,可省略if-else多層判斷鳞疲,給工廠方法傳入對(duì)應(yīng)的參數(shù)罪郊,利用多態(tài)性,實(shí)例化對(duì)應(yīng)的類尚洽。
(二)工廠模式結(jié)構(gòu)圖
1悔橄,工廠方法模式
2,抽象工廠模式
(三)簡單實(shí)現(xiàn)代碼
//工廠類
class Factor{
//生成對(duì)象方法
static function createDB(){
echo '我生產(chǎn)了一個(gè)DB實(shí)例';
return new DB;
}
}
//數(shù)據(jù)類
class DB{
public function __construct(){
echo __CLASS__.PHP_EOL;
}
}
$db=Factor::createDB();
(四)實(shí)現(xiàn)一個(gè)運(yùn)算器
//抽象運(yùn)算類
abstract class Operation{
abstract public function getVal($i,$j);//抽象方法不能包含方法體
}
//加法類
class OperationAdd extends Operation{
public function getVal($i,$j){
return $i+$j;
}
}
//減法類
class OperationSub extends Operation{
public function getVal($i,$j){
return $i-$j;
}
}
//計(jì)數(shù)器工廠
class CounterFactor {
private static $operation;
//工廠生產(chǎn)特定類對(duì)象方法
static function createOperation(string $operation){
switch($operation){
case '+' : self::$operation = new OperationAdd;
break;
case '-' : self::$operation = new OperationSub;
break;
}
return self::$operation;
}
}
$counter = CounterFactor::createOperation('+');
echo $counter->getVal(1,2);
缺點(diǎn):若是再增加一個(gè)乘法運(yùn)算,除了增加一個(gè)乘法運(yùn)算類之外癣疟,還得去工廠生產(chǎn)方法里面添加對(duì)應(yīng)的case代碼挣柬,違反了開放-封閉原則。
解決方法(1):通過傳入指定類名
//計(jì)算器工廠
class CounterFactor {
//工廠生產(chǎn)特定類對(duì)象方法
static function createOperation(string $operation){
return new $operation;
}
}
class OperationMul extends Operation{
public function getVal($i,$j){
return $i*$j;
}
}
$counter = CounterFactor::createOperation('OperationMul');
解決方法(2):通過抽象工廠模式
這里順帶提一個(gè)問題:如果我系統(tǒng)還有個(gè)生產(chǎn)一個(gè)文本輸入器工廠睛挚,那么那個(gè)工廠和這個(gè)計(jì)數(shù)器工廠又有什么關(guān)系呢邪蛔。
抽象高于實(shí)現(xiàn)
其實(shí)我們完全可以抽象出一個(gè)抽象工廠,然后將對(duì)應(yīng)的對(duì)象生產(chǎn)交給子工廠實(shí)現(xiàn)扎狱。代碼如下
//抽象運(yùn)算類
abstract class Operation{
abstract public function getVal($i,$j);//抽象方法不能包含方法體
}
//加法類
class OperationAdd extends Operation{
public function getVal($i,$j){
return $i+$j;
}
}
//乘法類
class OperationMul extends Operation{
public function getVal($i,$j){
return $i*$j;
}
}
//抽象工廠類
abstract class Factor{
abstract static function getInstance();
}
//加法器生產(chǎn)工廠
class AddFactor extends Factor {
//工廠生產(chǎn)特定類對(duì)象方法
static function getInstance(){
return new OperationAdd;
}
}
//減法器生產(chǎn)工廠
class MulFactor extends Factor {
static function getInstance(){
return new OperationMul;
}
}
//文本輸入器生產(chǎn)工廠
class TextFactor extends Factor{
static function getInstance(){}
}
$mul = MulFactor::getInstance();
echo $mul->getVal(1,2);
三侧到、建造者模式(Builder Pattern)
建造者模式(Builder Pattern):將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示淤击。
建造者模式是一步一步創(chuàng)建一個(gè)復(fù)雜的對(duì)象床牧,它允許用戶只通過指定復(fù)雜對(duì)象的類型和內(nèi)容就可以構(gòu)建它們,用戶不需要知道內(nèi)部的具體構(gòu)建細(xì)節(jié)遭贸。建造者模式屬于對(duì)象創(chuàng)建型模式戈咳。根據(jù)中文翻譯的不同,建造者模式又可以稱為生成器模式壕吹。
(一)為什么需要建造者模式
1著蛙,對(duì)象的生產(chǎn)需要復(fù)雜的初始化,比如給一大堆類成員屬性賦初值耳贬,設(shè)置一下其他的系統(tǒng)環(huán)境變量踏堡。使用建造者模式可以將這些初始化工作封裝起來。
2咒劲,對(duì)象的生成時(shí)可根據(jù)初始化的順序或數(shù)據(jù)不同顷蟆,而生成不同角色。
(二)建造者模式結(jié)構(gòu)圖
(三)模式應(yīng)用
在很多游戲軟件中腐魂,地圖包括天空帐偎、地面、背景等組成部分蛔屹,人物角色包括人體削樊、服裝、裝備等組成部分兔毒,可以使用建造者模式對(duì)其進(jìn)行設(shè)計(jì)漫贞,通過不同的具體建造者創(chuàng)建不同類型的地圖或人物
(四)設(shè)計(jì)實(shí)例
如果我們想創(chuàng)造出有一個(gè)person類,我們通過實(shí)例化時(shí)設(shè)置的屬性不同育叁,讓他們兩人一個(gè)是速度快的小孩迅脐,一個(gè)是知識(shí)深的長者
class person {
public $age;
public $speed;
public $knowledge;
}
//抽象建造者類
abstract class Builder{
public $_person;
public abstract function setAge();
public abstract function setSpeed();
public abstract function setKnowledge();
public function __construct(Person $person){
$this->_person=$person;
}
public function getPerson(){
return $this->_person;
}
}
//長者建造者
class OlderBuider extends Builder{
public function setAge(){
$this->_person->age=70;
}
public function setSpeed(){
$this->_person->speed="low";
}
public function setKnowledge(){
$this->_person->knowledge='more';
}
}
//小孩建造者
class ChildBuider extends Builder{
public function setAge(){
$this->_person->age=10;
}
public function setSpeed(){
$this->_person->speed="fast";
}
public function setKnowledge(){
$this->_person->knowledge='litte';
}
}
//建造指揮者
class Director{
private $_builder;
public function __construct(Builder $builder){
$this->_builder = $builder;
}
public function built(){
$this->_builder->setAge();
$this->_builder->setSpeed();
$this->_builder->setKnowledge();
}
}
//實(shí)例化一個(gè)長者建造者
$oldB = new OlderBuider(new Person);
//實(shí)例化一個(gè)建造指揮者
$director = new Director($oldB);
//指揮建造
$director->built();
//得到長者
$older = $oldB->getPerson();
var_dump($older);
(五)總結(jié)
使用建造者模式時(shí),我們把創(chuàng)建一個(gè)person實(shí)例的過程分為了兩步.
一步是先交給對(duì)應(yīng)角色的建造者豪嗽,如長者建造者谴蔑。這樣的好處就把角色的屬性設(shè)置封裝了起來豌骏,我們不用在new一個(gè)person時(shí),因?yàn)橐玫揭粋€(gè)older角色的實(shí)例树碱,而在外面寫了一堆$older->age=70肯适。
另一步是交給了一個(gè)建造指揮者变秦,調(diào)了一個(gè)built方法成榜,通過先設(shè)置age,再設(shè)置Speed的順序蹦玫,初始化這個(gè)角色赎婚。當(dāng)然在這個(gè)例子中,初始化的順序樱溉,是無所謂的挣输。但是如果對(duì)于一個(gè)建造漢堡,或是地圖福贞,初始化的順序不同撩嚼,可能就會(huì)得到不同的結(jié)果。
也許挖帘,你會(huì)說完丽,我直接設(shè)置也很方便呀。是的拇舀,對(duì)于某些情況是這樣的逻族。但是如果你考慮,我現(xiàn)在想增加一個(gè)青年人角色呢骄崩?如果我現(xiàn)在想讓建造有初始化有三種不同的順序呢聘鳞?
如果你使用了建造者模式,這兩個(gè)問題就簡單了要拂,增加一個(gè)青年人角色抠璃,那就增加一個(gè)青年年建造者類。初始化三種不同的順序脱惰,那么就在指揮建造者中增加兩種建造方法鸡典。
原型模式(Prototype Pattern)
原型模式(Prototype Pattern):與工廠模式類似,都是用來創(chuàng)建對(duì)象的枪芒。利用克隆來生成一個(gè)大對(duì)象彻况,減少創(chuàng)建時(shí)的初始化等操作占用開銷
(一)為什么需要原型模式
1,有些時(shí)候舅踪,我們需要?jiǎng)?chuàng)建多個(gè)類似的大對(duì)象纽甘。如果直接通過new對(duì)象,開銷很大抽碌,而且new完還得進(jìn)行重復(fù)的初始化工作悍赢【鐾可能把初始化工作封裝起來的,但是對(duì)于系統(tǒng)來說左权,你封不封裝皮胡,初始化工作還是要執(zhí)行。,
2赏迟,原型模式則不同屡贺,原型模式是先創(chuàng)建好一個(gè)原型對(duì)象,然后通過clone這個(gè)原型對(duì)象來創(chuàng)建新的對(duì)象锌杀,這樣就免去了重復(fù)的初始化工作甩栈,系統(tǒng)僅需內(nèi)存拷貝即可。
(二)原型模式結(jié)構(gòu)圖
(三)簡單實(shí)例
如果說糕再,我們現(xiàn)在正開發(fā)一個(gè)游戲量没,有不同的地圖,地圖大小都是一樣的突想,并且都有海洋殴蹄,但是不同的地圖溫度不一樣。
<?php
//抽象原型類
Abstract class Prototype{
abstract function __clone();
}
//具體原型類
class Map extends Prototype{
public $width;
public $height;
public $sea;
public function setAttribute(array $attributes){
foreach($attributes as $key => $val){
$this->$key = $val;
}
}
public function __clone(){}
}
//海洋類.這里就不具體實(shí)現(xiàn)了猾担。
class Sea{}
//使用原型模式創(chuàng)建對(duì)象方法如下
//先創(chuàng)建一個(gè)原型對(duì)象
$map_prototype = new Map;
$attributes = array('width'=>40,'height'=>60,'sea'=>(new Sea));
$map_prototype->setAttribute($attributes);
//現(xiàn)在已經(jīng)創(chuàng)建好原型對(duì)象了袭灯。如果我們要?jiǎng)?chuàng)建一個(gè)新的map對(duì)象只需要克隆一下
$new_map = clone $map_prototype;
var_dump($map_prototype);
var_dump($new_map);
通過上面的代碼,我們可以發(fā)現(xiàn)利用原型模式垒探,只需要實(shí)例化并初始化一個(gè)地圖原型對(duì)象妓蛮。以后生產(chǎn)一個(gè)地圖對(duì)象,都可以直接通過clone原型對(duì)象產(chǎn)生圾叼。省去了重新初始化的過程蛤克。
但是上面的代碼還是存在一些問題。那就是它只是一個(gè)淺拷貝
夷蚊,什么意思呢构挤?map原型對(duì)象有一個(gè)屬性sea存放了一個(gè)sea對(duì)象,在調(diào)用setAttribute的時(shí)候惕鼓,對(duì)象的賦值方式默認(rèn)是引用筋现。而當(dāng)我們克隆map對(duì)象時(shí),直接克隆了map的sea屬性箱歧,這就使得克隆出來的對(duì)象與原型對(duì)象的sea屬性對(duì)指向了矾飞,同一個(gè)sea對(duì)象的內(nèi)存空間。如果這個(gè)時(shí)候呀邢,我們改變了克隆對(duì)象的sea屬性洒沦,那么原型對(duì)象的sea屬性也跟著改變。
這顯然是不合理的价淌,我們想要的結(jié)果應(yīng)該是深拷貝
申眼,也就是改變克隆對(duì)象的所有屬性瞒津,包括用來存放sea這種其他對(duì)象的屬性時(shí),也不影響原型對(duì)象括尸。
當(dāng)然巷蚪,講到這里你可以當(dāng)我在胡說。但我還是建議你打印下原型對(duì)象和克隆對(duì)象濒翻,看一下他們的sea屬性吧屁柏,然后去好好了解一下什么叫深拷貝
和淺拷貝
。
(三)深拷貝的實(shí)現(xiàn)
深拷貝的實(shí)現(xiàn)肴焊,其實(shí)也簡單前联,我們只要實(shí)現(xiàn)Map類的克隆方法就行了功戚。這就是我們?yōu)槭裁匆x一個(gè)抽象原型類的原因娶眷。我們利用抽象類,強(qiáng)制所有繼承的具體原型類都必須來實(shí)現(xiàn)這個(gè)克隆方法啸臀。改進(jìn)如下:
//具體原型類
class Map extends Prototype{
public $width;
public $height;
public $sea;
public function setAttribute(array $attributes){
foreach($attributes as $key => $val){
$this->$key = $val;
}
}
//實(shí)現(xiàn)克隆方法届宠,用來實(shí)現(xiàn)深拷貝
public function __clone(){
$this->sea = clone $this->sea;
}
}
到這里原型模式就算實(shí)現(xiàn)了,但是我覺還可以進(jìn)一步進(jìn)行封裝响驴,利用工廠模式或建造者模式的思想阀湿。
(四)延伸
舉個(gè)例子蝠嘉,如果我們?cè)诳寺∵@個(gè)地圖對(duì)象的同時(shí)我們還需要進(jìn)行一下系統(tǒng)設(shè)置,或是說我們想給原型對(duì)象的clone_id屬性賦值當(dāng)前已經(jīng)拷貝了多少個(gè)對(duì)象的總數(shù)量轧铁?
我們可以把clone這個(gè)動(dòng)作封裝到一個(gè)類似的工廠方法里面去,簡單地實(shí)現(xiàn)一下旦棉,雖然不咋嚴(yán)謹(jǐn)齿风。
<?php
//抽象原型類
Abstract class Prototype{
abstract function __clone();
}
//具體原型類
class Map extends Prototype{
public $clone_id=0;
public $width;
public $height;
public $sea;
public function setAttribute(array $attributes){
foreach($attributes as $key => $val){
$this->$key = $val;
}
}
//實(shí)現(xiàn)克隆方法,用來實(shí)現(xiàn)深拷貝
public function __clone(){
$this->sea = clone $this->sea;
}
}
//海洋類.這里就不具體實(shí)現(xiàn)了绑洛。
class Sea{}
//克隆機(jī)器
class CloneTool{
static function clone($instance,$id){
$instance->clone_id ++;
system_write(get_class($instance));
return clone $instance;
}
}
//系統(tǒng)通知函數(shù)
function system_write($class){
echo "有人使用克隆機(jī)器克隆了一個(gè){$class}對(duì)象".PHP_EOL;
}
//使用原型模式創(chuàng)建對(duì)象方法如下
//先創(chuàng)建一個(gè)原型對(duì)象
$map_prototype = new Map;
$attributes = array('width'=>40,'height'=>60,'sea'=>(new Sea));
$map_prototype->setAttribute($attributes);
//現(xiàn)在已經(jīng)創(chuàng)建好原型對(duì)象了救斑。如果我們要?jiǎng)?chuàng)建一個(gè)新的map對(duì)象只需要克隆一下
$new_map = CloneTool::clone($map_prototype,1);
var_dump($map_prototype);
var_dump($new_map);
(五)模型應(yīng)用
多用于創(chuàng)建大對(duì)象,或初始化繁瑣的對(duì)象真屯。如游戲中的背景脸候,地圖。web中的畫布等等
五绑蔫、創(chuàng)建型設(shè)計(jì)模式雜談
單例模式运沦,工廠模式,建造者模式配深,原型模式都屬于
創(chuàng)建型模式
携添。使用創(chuàng)建型模式的目的,就是為了創(chuàng)建一個(gè)對(duì)象凉馆。創(chuàng)建型模式的優(yōu)點(diǎn)薪寓,在于如何把復(fù)雜的創(chuàng)建過程封裝起來亡资,如何降低系統(tǒng)的內(nèi)銷。
我認(rèn)為創(chuàng)建型模式的一個(gè)總要的思想其實(shí)就是
封裝
向叉,利用封裝锥腻,把直接獲得一個(gè)對(duì)象改為通過一個(gè)接口獲得一個(gè)對(duì)象。這樣最明顯的優(yōu)點(diǎn)母谎,在于我們可以把一些復(fù)雜的操作也封裝到接口里去瘦黑,我們使用時(shí)直接調(diào)這個(gè)接口就可以了。具體的實(shí)現(xiàn)奇唤,我們?cè)谥骶€程序中就不再考慮幸斥。這樣使得我們的代碼看上去更少,更簡潔咬扇。單例模式
甲葬,我們把對(duì)象的生成從new改為通過一個(gè)靜態(tài)方法,通過靜態(tài)方法的控制懈贺,使得我們總是返回同一個(gè)實(shí)例給調(diào)用者经窖,確保了系統(tǒng)只有一個(gè)實(shí)例工廠模式
,也是一樣梭灿,生成對(duì)象改為接口画侣,還可以通過傳參實(shí)例化不同的類。如果我們通過直接new的話堡妒,那么我們?cè)谥骶€代碼中少不了要寫if condition new 一個(gè)加法類配乱,else new一個(gè)減法類。封裝了之后皮迟,我們通過接口傳參搬泥,還能利用多態(tài)的特性去替代if else語句。
而且我們遵循了單一原則万栅,讓類的功能單一佑钾。我們?nèi)绻枰粋€(gè)新功能,只需添加一個(gè)類烦粒,不用修改其他類的功能休溶。這樣使得代碼的擴(kuò)展性更好了。建造者模式
扰她,我們把初始化的工作和順序兽掰,封裝給了一個(gè)建造者和指揮者。如果徒役,我們下次要建造的類屬性孽尽,或是順序不同。我們只需新建對(duì)應(yīng)的建造者類或添加對(duì)應(yīng)的指揮者方法忧勿,不必再去修改原代碼杉女。而且我們也省去了瞻讽,這new對(duì)象后,還要寫$attribut=array();這種一大串?dāng)?shù)組熏挎,然后調(diào)好幾個(gè)方法去初始化的工作速勇。原型模式
,通過先創(chuàng)建一個(gè)原型對(duì)象坎拐,然后直接克隆烦磁,省去了new大對(duì)象帶來的開銷浪費(fèi)。當(dāng)然我們同樣可以通過哼勇,封裝clone這個(gè)動(dòng)作都伪。使得我們?cè)赾lone的同時(shí)還可以做一些其他的準(zhǔn)備工作。
感謝閱讀积担,由于筆者也是初學(xué)設(shè)計(jì)模式陨晶,能力有限,文章不可避免地有失偏頗
后續(xù)更新** PHP設(shè)計(jì)模式-結(jié)構(gòu)型設(shè)計(jì)模式 **介紹磅轻,歡迎大家評(píng)論指正
我最近的學(xué)習(xí)總結(jié):