php設計模式之原型模式

2022-03-03 12:36:21 字數 2955 閱讀 2001

原型模式(prototype pattern):與工廠模式類似,都是用來建立物件的。利用轉殖來生成乙個大物件,減少建立時的初始化等操作占用開銷

(一)為什麼需要原型模式

1,有些時候,我們需要建立多個類似的大物件。如果直接通過new物件,開銷很大,而且new完還得進行重複的初始化工作。可能把初始化工作封裝起來的,但是對於系統來說,你封不封裝,初始化工作還是要執行。,

2,原型模式則不同,原型模式是先建立好乙個原型物件,然後通過clone這個原型物件來建立新的物件,這樣就免去了重複的初始化工作,系統僅需記憶體拷貝即可。

(二)原型模式結構圖

(三)簡單例項

如果說,我們現在正開發乙個遊戲,有不同的地圖,地圖大小都是一樣的,並且都有海洋,但是不同的地圖溫度不一樣。

<?php 

//抽象原型類

abstract

class

prototype

//具體原型類

class map extends

prototype

}public

function

__clone(){}}//

海洋類.這裡就不具體實現了。

class

sea{}

//使用原型模式建立物件方法如下

//先建立乙個原型物件

$map_prototype = new

map;

$attributes = array('width'=>40,'height'=>60,'sea'=>(new

sea));

$map_prototype->setattribute($attributes

);//

現在已經建立好原型物件了。如果我們要建立乙個新的map物件只需要轉殖一下

$new_map = clone

$map_prototype

;var_dump($map_prototype

);var_dump($new_map);

通過上面的**,我們可以發現利用原型模式,只需要例項化並初始化乙個地圖原型物件。以後生產乙個地圖物件,都可以直接通過clone原型物件產生。省去了重新初始化的過程。

但是上面的**還是存在一些問題。那就是它只是乙個淺拷貝,什麼意思呢?map原型物件有乙個屬性sea存放了乙個sea物件,在呼叫setattribute的時候,物件的賦值方式預設是引用。而當我們轉殖map物件時,直接轉殖了map的sea屬性,這就使得轉殖出來的物件與原型物件的sea屬性對指向了,同乙個sea物件的記憶體空間。如果這個時候,我們改變了轉殖物件的sea屬性,那麼原型物件的sea屬性也跟著改變。

這顯然是不合理的,我們想要的結果應該是深拷貝,也就是改變轉殖物件的所有屬性,包括用來存放sea這種其他物件的屬性時,也不影響原型物件。

當然,講到這裡你可以當我在胡說。但我還是建議你列印下原型物件和轉殖物件,看一下他們的sea屬性吧,然後去好好了解一下什麼叫深拷貝和淺拷貝。

(三)深拷貝的實現

深拷貝的實現,其實也簡單,我們只要實現map類的轉殖方法就行了。這就是我們為什麼要定義乙個抽象原型類的原因。我們利用抽象類,強制所有繼承的具體原型類都必須來實現這個轉殖方法。改進如下:

//

具體原型類

class map extends

prototype

}//實現轉殖方法,用來實現深拷貝

public

function

__clone()

}

到這裡原型模式就算實現了,但是我覺還可以進一步進行封裝,利用工廠模式或建造者模式的思想。

(四)延伸

舉個例子,如果我們在轉殖這個地圖物件的同時我們還需要進行一下系統設定,或是說我們想給原型物件的clone_id屬性賦值當前已經拷貝了多少個物件的總數量?

我們可以把clone這個動作封裝到乙個類似的工廠方法裡面去,簡單地實現一下,雖然不咋嚴謹。

<?php 

//抽象原型類

abstract

class

prototype

//具體原型類

class map extends

prototype

}//實現轉殖方法,用來實現深拷貝

public

function

__clone()}//

海洋類.這裡就不具體實現了。

class

sea{}

//轉殖機器

class

clonetool}//

系統通知函式

function system_write($class

)物件".php_eol;}

//使用原型模式建立物件方法如下

//先建立乙個原型物件

$map_prototype = new

map;

var_dump($map_prototype

);$attributes = array('width'=>40,'height'=>60,'sea'=>(new

sea));

$map_prototype->setattribute($attributes

);//

現在已經建立好原型物件了。如果我們要建立乙個新的map物件只需要轉殖一下

$new_map = clonetool::clone($map_prototype

);$two_map = clonetool::clone($map_prototype

);echo '

';echo '

';var_dump($new_map

);echo '

';var_dump($two_map);

(五)模型應用

多用於建立大物件,或初始化繁瑣的物件。如遊戲中的背景,地圖。web中的畫布等等

PHP 設計模式之原型模式

1.與工廠模式類似,都是用來建立物件的 2.與工廠模式實現不同,原型模式是先建立好原型物件,然後通過 clone 原型物件來建立新的物件的。這樣就避免了類建立時重複的初始化操作 3.原型模式適用於大物件的建立,每建立乙個大物件需要很大的開銷,如果每次 new 就會消耗很大,原型模式僅需要記憶體拷貝即...

PHP設計模式之原型模式

原型模式其實更形象的來說應該叫轉殖模式。它主要的行為是對物件進行轉殖,但是又把被轉殖的物件稱之為最初的原型,於是,這個模式就這樣被命名了。說真的,從使用方式來看真的感覺叫轉殖模式更貼切一些。gof定義 用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件 gof類圖 實現 abstract...

PHP 設計模式 原型模式

原型模式 prototype pattern 與工廠模式類似,都是用來建立物件的。利用轉殖來生成乙個大物件,減少建立時的初始化等操作占用開銷 1,有些時候,我們需要建立多個類似的大物件。如果直接通過new物件,開銷很大,而且new完還得進行重複的初始化工作。可能把初始化工作封裝起來的,但是對於系統來...