學(xué)習(xí)php設(shè)計(jì)模式 php實(shí)現(xiàn)享元模式(flyweight)
一、意圖
運(yùn)用共享技術(shù)有效的支持大量細(xì)粒度的對(duì)象
享元模式變化的是對(duì)象的存儲(chǔ)開銷
二、享元模式結(jié)構(gòu)圖
三、享元模式中主要角色
抽象享元(Flyweight)角色:此角色是所有的具體享元類的超類,為這些類規(guī)定出需要實(shí)現(xiàn)的公共接口。那些需要外蘊(yùn)狀態(tài)的操作可以通過調(diào)用商業(yè)以參數(shù)形式傳入
具體享元(ConcreteFlyweight)角色:實(shí)現(xiàn)Flyweight接口,并為內(nèi)部狀態(tài)(如果有的話)拉回存儲(chǔ)空間。ConcreteFlyweight對(duì)象必須是可共享的。它所存儲(chǔ)的狀態(tài)必須是內(nèi)部的
不共享的具體享元(UnsharedConcreteFlyweight)角色:并非所有的Flyweight子類都需要被共享。Flyweigth使共享成為可能,但它并不強(qiáng)制共享。
享元工廠(FlyweightFactory)角色:負(fù)責(zé)創(chuàng)建和管理享元角色。本角色必須保證享元對(duì)象可能被系統(tǒng)適當(dāng)?shù)毓蚕?br />
客戶端(Client)角色:本角色需要維護(hù)一個(gè)對(duì)所有享元對(duì)象的引用。本角色需要自行存儲(chǔ)所有享元對(duì)象的外部狀態(tài)
四、享元模式的優(yōu)點(diǎn)和缺點(diǎn)
享元模式的優(yōu)點(diǎn):Flyweight模式可以大幅度地降低內(nèi)存中對(duì)象的數(shù)量。
享元模式的缺點(diǎn):
1、Flyweight模式使得系統(tǒng)更加復(fù)雜
2、Flyweigth模式將享元對(duì)象的狀態(tài)外部化,而讀取外部狀態(tài)使得運(yùn)行時(shí)間稍微變長
五、享元模式適用場景
當(dāng)以下情況都成立時(shí)使用Flyweight模式:
1、一個(gè)應(yīng)用程序使用了大量的對(duì)象
2、完全由于使用大量的對(duì)象,造成很大的存儲(chǔ)開銷
3、對(duì)象的大多數(shù)狀態(tài)都可變?yōu)橥獠繝顟B(tài)
4、如果刪除對(duì)象的外部狀態(tài),那么可以用相對(duì)較少的共享對(duì)象取代很多組對(duì)象
5、應(yīng)用程序不依賴于對(duì)象標(biāo)識(shí)。
六、享元模式與其它模式
單例模式(Singleton):客戶端要引用享元對(duì)象,是通過工廠對(duì)象創(chuàng)建或者獲得的,客戶端每次引用一個(gè)享元對(duì)象,都是可以通過同一個(gè)工廠對(duì)象來引用所需要的享元對(duì)象。因此,可以將享元工廠設(shè)計(jì)成單例模式,這樣就可以保證客戶端只引用一個(gè)工廠實(shí)例。因?yàn)樗械南碓獙?duì)象都是由一個(gè)工廠對(duì)象統(tǒng)一管理的,所以在客戶端沒有必要引用多個(gè)工廠對(duì)象。不管是單純享元模式還是復(fù)合享元模式中的享元工廠角色,都可以設(shè)計(jì)成為單例模式,對(duì)于結(jié)果是不會(huì)有任何影響的。
Composite模式:復(fù)合享元模式實(shí)際上是單純享元模式與合成模式的組合。單純享元對(duì)象可以作為樹葉對(duì)象來講,是可以共享的,而復(fù)合享元對(duì)象可以作為樹枝對(duì)象,因此在復(fù)合享元角色中可以添加聚集管理方法。
七、享元模式PHP示例
<?php /** * 抽象享元角色 */ abstract class Flyweight { /** * 示意性方法 * @param string $state 外部狀態(tài) */ abstract public function operation($state); } /** * 具體享元角色 */ class ConcreteFlyweight extends Flyweight { private $_intrinsicState = null; /** * 構(gòu)造方法 * @param string $state 內(nèi)部狀態(tài) */ public function __construct($state) { $this->_intrinsicState = $state; } public function operation($state) { echo 'ConcreteFlyweight operation, Intrinsic State = ' . $this->_intrinsicState . ' Extrinsic State = ' . $state . '<br />'; } } /** * 不共享的具體享元,客戶端直接調(diào)用 */ class UnsharedConcreteFlyweight extends Flyweight { private $_intrinsicState = null; /** * 構(gòu)造方法 * @param string $state 內(nèi)部狀態(tài) */ public function __construct($state) { $this->_intrinsicState = $state; } public function operation($state) { echo 'UnsharedConcreteFlyweight operation, Intrinsic State = ' . $this->_intrinsicState . ' Extrinsic State = ' . $state . '<br />'; } } /** * 享元工廠角色 */ class FlyweightFactory { private $_flyweights; public function __construct() { $this->_flyweights = array(); } public function getFlyweigth($state) { if (isset($this->_flyweights[$state])) { return $this->_flyweights[$state]; } else { return $this->_flyweights[$state] = new ConcreteFlyweight($state); } } } /** * 客戶端 */ class Client { /** * Main program. */ public static function main() { $flyweightFactory = new FlyweightFactory(); $flyweight = $flyweightFactory->getFlyweigth('state A'); $flyweight->operation('other state A'); $flyweight = $flyweightFactory->getFlyweigth('state B'); $flyweight->operation('other state B'); /* 不共享的對(duì)象,單獨(dú)調(diào)用 */ $uflyweight = new UnsharedConcreteFlyweight('state A'); $uflyweight->operation('other state A'); } } Client::main(); ?>
八、復(fù)合享元模式
復(fù)合享元模式對(duì)象是由一些單純享元使用合成模式加以復(fù)合而成
復(fù)合享元角色所代表的對(duì)象是不可以共享的,但是一個(gè)復(fù)合享元對(duì)象可以分解成為多個(gè)本身是單純享元對(duì)象的組合。
九、復(fù)合享元模式PHP示例
<?php /** * 抽象享元角色 */ abstract class Flyweight { /** * 示意性方法 * @param string $state 外部狀態(tài) */ abstract public function operation($state); } /** * 具體享元角色 */ class ConcreteFlyweight extends Flyweight { private $_intrinsicState = null; /** * 構(gòu)造方法 * @param string $state 內(nèi)部狀態(tài) */ public function __construct($state) { $this->_intrinsicState = $state; } public function operation($state) { echo 'ConcreteFlyweight operation, Intrinsic State = ' . $this->_intrinsicState . ' Extrinsic State = ' . $state . '<br />'; } } /** * 不共享的具體享元,客戶端直接調(diào)用 */ class UnsharedConcreteFlyweight extends Flyweight { private $_flyweights; /** * 構(gòu)造方法 * @param string $state 內(nèi)部狀態(tài) */ public function __construct() { $this->_flyweights = array(); } public function operation($state) { foreach ($this->_flyweights as $flyweight) { $flyweight->operation($state); } } public function add($state, Flyweight $flyweight) { $this->_flyweights[$state] = $flyweight; } } /** * 享元工廠角色 */ class FlyweightFactory { private $_flyweights; public function __construct() { $this->_flyweights = array(); } public function getFlyweigth($state) { if (is_array($state)) { // 復(fù)合模式 $uFlyweight = new UnsharedConcreteFlyweight(); foreach ($state as $row) { $uFlyweight->add($row, $this->getFlyweigth($row)); } return $uFlyweight; } else if (is_string($state)) { if (isset($this->_flyweights[$state])) { return $this->_flyweights[$state]; } else { return $this->_flyweights[$state] = new ConcreteFlyweight($state); } } else { return null; } } } /** * 客戶端 */ class Client { /** * Main program. */ public static function main() { $flyweightFactory = new FlyweightFactory(); $flyweight = $flyweightFactory->getFlyweigth('state A'); $flyweight->operation('other state A'); $flyweight = $flyweightFactory->getFlyweigth('state B'); $flyweight->operation('other state B'); /* 復(fù)合對(duì)象*/ $uflyweight = $flyweightFactory->getFlyweigth(array('state A', 'state B')); $uflyweight->operation('other state A'); } } Client::main(); ?>
十、PHP中享元模式的地位
相對(duì)于其它模式,F(xiàn)lyweight模式在PHP的現(xiàn)有版本中沒有太大的意義,因?yàn)镻HP的生命周期是頁面級(jí)的,即從一個(gè)PHP文件執(zhí)行開始會(huì)載入所需的資源,當(dāng)執(zhí)行完畢后,這些所有的資源會(huì)被全部釋放,而一般來說我們也不會(huì)讓一個(gè)頁面執(zhí)行太長時(shí)間。
以上就是使用php實(shí)現(xiàn)享元模式的代碼,還有一些關(guān)于享元模式的概念區(qū)分,希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
使用PHPMYADMIN操作mysql數(shù)據(jù)庫添加新用戶和數(shù)據(jù)庫的方法
在Mysql中創(chuàng)建多用戶,為了讓每個(gè)用戶在使用phpmyadmin管理數(shù)據(jù)庫時(shí),只能看到自己同名的數(shù)據(jù)庫,所以在設(shè)置用戶權(quán)限時(shí)要特別注意!可以參考以下步驟設(shè)置用戶權(quán)限。2010-04-04PHP將session信息存儲(chǔ)到數(shù)據(jù)庫的類實(shí)例
這篇文章主要介紹了PHP將session信息存儲(chǔ)到數(shù)據(jù)庫的類,實(shí)例分析了php封裝的session信息存儲(chǔ)到數(shù)據(jù)庫的類,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03php中isset與empty函數(shù)的困惑與用法分析
這篇文章主要介紹了php中isset與empty函數(shù)的困惑與用法,結(jié)合實(shí)例形式分析了php中isset與empty函數(shù)的功能、用法、區(qū)別及相關(guān)使用注意事項(xiàng),需要的朋友可以參考下2019-07-07Thinkphp5和Thinkphp3的區(qū)別對(duì)比以及單字母函數(shù)對(duì)應(yīng)的助手函數(shù)
TP5在很多方面相比TP3升級(jí)和提升。盡管TP3已經(jīng)有一定的市場和用戶群體,但新項(xiàng)目還是建議使用TP5。thinkphp3.2中一些快捷大寫單字母函數(shù),比如 U(),I() , C(),M() , D() , W()等,這些在thinkphp5 中已經(jīng)不再使用,而是改用助手函數(shù)來代替。2023-07-07PHP登錄驗(yàn)證碼的實(shí)現(xiàn)與使用方法
這篇文章主要介紹了PHP登錄驗(yàn)證碼的實(shí)現(xiàn)與使用方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了php驗(yàn)證碼圖片的生成、顯示、判斷等相關(guān)步驟與使用技巧,需要的朋友可以參考下2016-07-07PHP小技巧之JS和CSS優(yōu)化工具M(jìn)inify的使用方法
為減少HTTP請(qǐng)求,我們往往需要合并和壓縮多個(gè)JS和CSS文件,下面記錄下網(wǎng)上關(guān)于實(shí)現(xiàn)這個(gè)功能的PHP源碼以及開源項(xiàng)目Minify的使用方法2014-05-05php實(shí)現(xiàn)微信企業(yè)號(hào)支付個(gè)人的方法詳解
這篇文章主要介紹了php實(shí)現(xiàn)微信企業(yè)號(hào)支付個(gè)人的方法,詳細(xì)分析了php微信企業(yè)號(hào)的支付配置、證書使用及支付流程相關(guān)操作技巧,需要的朋友可以參考下2017-07-07jQuery中的RadioButton,input,CheckBox取值賦值實(shí)現(xiàn)代碼
本篇文章主要是對(duì)jQuery中的RadioButton,input,CheckBox取值賦值實(shí)現(xiàn)代碼進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2014-02-02