極簡設計模式-享元模式

long2ge發表於2021-12-04

定義

運用共享技術有效地支援大量細粒度物件的複用。
系統只使用少量的物件,而這些物件都很相似,狀態變化很小,可以實現物件的多次複用。

享元概念

內部狀態
    在享元物件中可共享的狀態叫內部狀態。
外部狀態
    在享元物件中不可共享的狀態叫外部狀態。
享元池
    享元工廠裡面存在享元物件的變數叫做享元池。

設計的原則和思想

  1. 解耦的是享元物件中的內部狀態和外部狀態。
  2. 不變部分是內部狀態,變化部分是外部狀態。
  3. 核心思想是物件複用,節省記憶體。

一句話概括設計模式

共享物件。

結構中包含的角色

  1. Flyweight(抽象享元類)
  2. ConcreteFlyweight(具體享元類)
  3. UnsharedConcreteFlyweight(非共享具體享元類)
  4. FlyweightFactory(享元工廠類)

最小可表達程式碼

// 抽象享元類  
abstract class Flyweight {} 

// 具體享元類  
class ConcreteFlyweight extends Flyweight {}

// 非共享具體享元類
class UnsharedConcreteFlyweight extends Flyweight 
{
    private $flyweights = [];

    public function add($id, $flyweight)
    {
        $this->flyweights[$id] = $flyweight;
    }
}

// 享元工廠類
class FlyweightFactory 
{
    private static $flyweights = [];

    public static function getFlyweightById(int $id)
    {  
        if (empty(static::$flyweights[$id])) {
            var_dump("生成ID : {$id}");
            static::$flyweights[$id] = new ConcreteFlyweight();
        }

        return static::$flyweights[$id];
    }

    public static function getUnsharedConcreteFlyweightByIds(array $ids)
    {  
        $unsharedConcreteFlyweight = new UnsharedConcreteFlyweight(); 

        foreach ($ids as $id) {
            $unsharedConcreteFlyweight->add($id, self::getFlyweightById($id));
        }

        return $unsharedConcreteFlyweight;
    }  
}

$id = 1;
$ids = [1,2];
$flyweight = FlyweightFactory::getFlyweightById($id);
$unsharedConcreteFlyweight = FlyweightFactory::getUnsharedConcreteFlyweightByIds($ids);

優點

  1. 大大減少物件的建立,使效率提高。
  2. 節省記憶體,減少記憶體中物件的數量。
  3. 享元物件可以在不同的環境中被共享。

缺點

  1. 分離出內部狀態和外部狀態,使系統和程式碼都更加複雜。

何時使用

  1. 有大量相同或者相似的物件,造成記憶體的大量耗費。
  2. 需要多次重複使用享元物件時。
  3. 程式必須支援大量物件且沒有足夠的記憶體容量時。
  4. 需要緩衝池的場景。

實際應用場景

  1. JAVA 中的 String。
  2. 資料庫的連線池。

享元模式 VS 物件池模式 VS 多例模式

享元模式

  1. 主要目的是節省空間。
  2. 在整個生命週期中,是被所有使用者共享的。
  3. 主要用於減少建立物件的數量,以減少記憶體佔用和提高效能。
  4. 一個類可以建立多個物件,每個物件被多處程式碼引用共享。

物件池模式

  1. 主要目的是節省時間。
  2. 在任意時刻都不會被多處使用,而是被一個使用者獨佔,當使用完成之後,放回到池中,再由其他使用者重複利用。

多例模式

  1. 主要目的是為了限制物件的個數。
本作品採用《CC 協議》,轉載必須註明作者和本文連結
Long2Ge

相關文章