一、意圖
運用共享技術有效的支持大量細粒度的對象
享元模式變化的是對象的存儲開銷
二、享元模式結構圖
三、享元模式中主要角色
抽象享元(Flyweight)角色:此角色是所有的具體享元類的超類,為這些類規定出需要實現的公共接口。那些需要外蘊狀態的操作可以通過調用商業以參數形式傳入
具體享元(ConcreteFlyweight)角色:實現Flyweight接口,並為內部狀態(如果有的話)拉回存儲空間。ConcreteFlyweight對象必須是可共享的。它所存儲的狀態必須是內部的
不共享的具體享元(UnsharedConcreteFlyweight)角色:並非所有的Flyweight子類都需要被共享。Flyweigth使共享成為可能,但它並不強制共享。
享元工廠(FlyweightFactory)角色:負責創建和管理享元角色。本角色必須保證享元對象可能被系統適當地共享
客戶端(Client)角色:本角色需要維護一個對所有享元對象的引用。本角色需要自行存儲所有享元對象的外部狀態
四、享元模式的優點和缺點
享元模式的優點:Flyweight模式可以大幅度地降低內存中對象的數量。
享元模式的缺點:
1、Flyweight模式使得系統更加復雜
2、Flyweigth模式將享元對象的狀態外部化,而讀取外部狀態使得運行時間稍微變長
五、享元模式適用場景
當以下情況都成立時使用Flyweight模式:
1、一個應用程序使用了大量的對象
2、完全由於使用大量的對象,造成很大的存儲開銷
3、對象的大多數狀態都可變為外部狀態
4、如果刪除對象的外部狀態,那麼可以用相對較少的共享對象取代很多組對象
5、應用程序不依賴於對象標識。
六、享元模式與其它模式
單例模式(Singleton):客戶端要引用享元對象,是通過工廠對象創建或者獲得的,客戶端每次引用一個享元對象,都是可以通過同一個工廠對象來引用所需要的享元對象。因此,可以將享元工廠設計成單例模式,這樣就可以保證客戶端只引用一個工廠實例。因為所有的享元對象都是由一個工廠對象統一管理的,所以在客戶端沒有必要引用多個工廠對象。不管是單純享元模式還是復合享元模式中的享元工廠角色,都可以設計成為單例模式,對於結果是不會有任何影響的。
Composite模式:復合享元模式實際上是單純享元模式與合成模式的組合。單純享元對象可以作為樹葉對象來講,是可以共享的,而復合享元對象可以作為樹枝對象,因此在復合享元角色中可以添加聚集管理方法。
七、享元模式PHP示例
<?php /** * 抽象享元角色 */ abstract class Flyweight { /** * 示意性方法 * @param string $state 外部狀態 */ abstract public function operation($state); } /** * 具體享元角色 */ class ConcreteFlyweight extends Flyweight { private $_intrinsicState = null; /** * 構造方法 * @param string $state 內部狀態 */ public function __construct($state) { $this->_intrinsicState = $state; } public function operation($state) { echo 'ConcreteFlyweight operation, Intrinsic State = ' . $this->_intrinsicState . ' Extrinsic State = ' . $state . '<br />'; } } /** * 不共享的具體享元,客戶端直接調用 */ class UnsharedConcreteFlyweight extends Flyweight { private $_intrinsicState = null; /** * 構造方法 * @param string $state 內部狀態 */ 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'); /* 不共享的對象,單獨調用 */ $uflyweight = new UnsharedConcreteFlyweight('state A'); $uflyweight->operation('other state A'); } } Client::main(); ?>
八、復合享元模式
復合享元模式對象是由一些單純享元使用合成模式加以復合而成
復合享元角色所代表的對象是不可以共享的,但是一個復合享元對象可以分解成為多個本身是單純享元對象的組合。
九、復合享元模式PHP示例
<?php /** * 抽象享元角色 */ abstract class Flyweight { /** * 示意性方法 * @param string $state 外部狀態 */ abstract public function operation($state); } /** * 具體享元角色 */ class ConcreteFlyweight extends Flyweight { private $_intrinsicState = null; /** * 構造方法 * @param string $state 內部狀態 */ public function __construct($state) { $this->_intrinsicState = $state; } public function operation($state) { echo 'ConcreteFlyweight operation, Intrinsic State = ' . $this->_intrinsicState . ' Extrinsic State = ' . $state . '<br />'; } } /** * 不共享的具體享元,客戶端直接調用 */ class UnsharedConcreteFlyweight extends Flyweight { private $_flyweights; /** * 構造方法 * @param string $state 內部狀態 */ 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)) { // 復合模式 $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'); /* 復合對象*/ $uflyweight = $flyweightFactory->getFlyweigth(array('state A', 'state B')); $uflyweight->operation('other state A'); } } Client::main(); ?>
十、PHP中享元模式的地位
相對於其它模式,Flyweight模式在PHP的現有版本中沒有太大的意義,因為PHP的生命周期是頁面級的,即從一個PHP文件執行開始會載入所需的資源,當執行完畢後,這些所有的資源會被全部釋放,而一般來說我們也不會讓一個頁面執行太長時間。
以上就是使用php實現享元模式的代碼,還有一些關於享元模式的概念區分,希望對大家的學習有所幫助。