設計模式--享元模式C++實現


1定義

使用共享對象可有效的支持大量細粒度的對象

2類圖

角色分析

Flyweight抽象享元角色,一個產品的抽象,定義內部狀態和外部狀態的接口或者實現

ConcreteFlyweight具體享元角色,實現抽象角色定義的業務。注:內部狀態處理和環境無關

unsharedConcreteFlyweight不可共享的享元角色,不存在外部狀態或者安全要求,不能夠使用共性技術的對象,該對象一般不會出現在享元工廠中

Flyweight享元工廠,就是構造一個池容器,同時提供從翅中獲得對象的方法

3實現

#pragma once 
#include<hash_map>
#include<iostream>
using namespace std;

class Flyweight
{
private:
    //內部狀態
    string intrinsic;
protected:
    //外部狀態
    const string extrainsic;
public:
    Flyweight(string _ex)
        :extrainsic ( _ex)
    {
    }

    //定義業務操作
    virtual void operate(){}
    string getIntrinsic()
    {
        return intrinsic;
    }
    void setIntrinsic(string _in)
    {
        intrinsic = _in;
    }
};

class ConcreteFlyweight1 :public Flyweight
{
public:
    ConcreteFlyweight1(string ex)
        :Flyweight(ex)
    {}

    void operate()
    {
        //根據外部邏輯進行業務處理
        cout << "1根據外部邏輯進行業務處理!" << endl;
    }
};
class ConcreteFlyweight2 :public Flyweight
{
public:
    ConcreteFlyweight2(string ex)
        :Flyweight(ex)
    {}

    void operate()
    {
        //根據外部邏輯進行業務處理
        cout << "2根據外部邏輯進行業務處理!" << endl;
    }
};
class FlyweightFactory
{
private:
    static hash_map<string, Flyweight*> pool;
public:
    Flyweight* getFlyweight(string ex)
    {
        hash_map<string, Flyweight*>::iterator it = pool.find(ex);
        if (it == pool.end())
        {
            cout << "Creat Flyweight1" << endl;
            pool[ex] = new ConcreteFlyweight1(ex);
        }
        return pool[ex];
    }
};


hash_map<string, Flyweight*> FlyweightFactory::pool = hash_map<string,Flyweight*>();
class Client
{
public:
    void operator()()
    {
        FlyweightFactory ff;
        Flyweight * pf = ff.getFlyweight("lianglihui");
        pf->operate();
    }
};

 

4應用

①優點

是一個簡單的模式,可以大大減少程序創建的對象,降低內存占用,增強性能

②缺點

提高系統復雜性,需要分離狀態,且外部狀態不應該隨着內部狀態的改變而改變

③使用場景

系統中存在大量的相似對象

細粒度的對象都具有較接近的外部狀態,而內部狀態和環境無關。

需要緩沖池的場景

5擴展

① 線程安全問題,因為共享對象比較少,多個線程同時去訪問通過外部狀態對其內部狀態訪問就出現了線程安全問題。--》使用享元模式時,保證享元對象足夠多,同時處理掉線程安全問題就好

②性能問題

優化:將外部狀態封裝成類,通過橋梁模式進行嫁接,減少耦合,提高效率/使用系統內置類型作為外部狀態

(ps因為池中檢測會有調用消耗)

6對象池vs享元模式

享元模式可以實現對象池

對象池着重在對象的復用,池中的每個對象都是可替換的,從同一個池中獲得A對象和B對象對客戶端來講是完全相同的,主要解決復用。

享元模式側重共享問題,如何建立多個可共享的細粒度對象則是其關注的重點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM