設計模式之十三:Flyweight(享元)—對象結構型模式

2014-06-15 星期日 9:35:04 

Flyweight,繼續GOF。

1、Intent

Use sharing to support large numbers of fine-grained objects efficiently.

運用共享技術有效地支持大量細粒度的對象。

2、Also Known As
3、Motivation

A flyweightis a shared object that can be used in multiple contexts simultaneously. The flyweight acts as an independent object in each context—it's indistinguishable from an instance of the object that's not shared. 

Flyweights cannot make assumptions about the context in which they operate. The key concept here is the distinction between intrinsicand extrinsicstate. Intrinsic state is stored in the flyweight; it consists of information that's independent of the flyweight's context, thereby making it sharable. Extrinsic state depends on and varies with the flyweight's context and therefore can't be shared. Client objects are responsible for passing extrinsic state to the flyweight when it needs it.

flyweight是一個共享對象,它可以同時在多個場景 ( context ) 中使用,並且在每個場景中flyweight都可以作爲一個獨立的對象—這一點與非共享對象的實例沒有區別。

flyweight不能對它所運行的場景做出任何假設,這裏的關鍵概念是內部狀態和外部狀態之間的區別。內部狀態存儲於 flyweight 中,它包含了獨立於 flyweigh t場景的信息,這些信息使得 flyweight 可以被共享。而外部狀態取決於 Flyweight場景,並根據場景而變化,因此不可共享。用戶對象負責在必要的時候將外部狀態傳遞給 Flyweight。


4、Applicability

The Flyweight pattern's effectiveness depends heavily on how and where it's used. Apply the Flyweight pattern when allof the following are true:

●  An application uses a large number of objects.

●  Storage costs are high because of the sheer quantity of objects.

●  Most object state can be made extrinsic.

●  Many groups of objects may be replaced by relatively few shared objects once extrinsic state is removed.

●  The application doesn't depend on object identity. Since flyweight objects may be shared, identity tests will return true for conceptually distinct objects.

在以下情況使用享元模式:

  一個應用程序使用了大量的對象。

  完全由於使用大量的對象,造成很大的存儲開銷。

  對象的大多數狀態都可變爲外部狀態。

  如果刪除對象的外部狀態,那麼可以用相對較少的共享對象取代很多組對象。

 應用程序不依賴於對象標識。由於 F l y w e i g h t對象可以被共享,對於概念上明顯有別的對象,標識測試將返回真值。

5、Structure


6、代碼

代碼採用此鏈接的  http://www.cnblogs.com/jiese/p/3171463.html。Flyweight主要要分出共同和不同的部分。



  • Flyweight.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#ifndef _FLYWEIGHT_H_
#define _FLYWEIGHT_H_
 
#include <string>
#include <vector>
 
using namespace std;
 
//基類,定義操作接口Operation
class Flyweight
{
public:
    //操作外部狀態extrinsicState
    virtual void Operation(const string& extrinsicState)=0;
    string GetIntrinsicState();
    virtual ~Flyweight();
protected:
    Flyweight(string intrinsicState);
private:
    //內部狀態,也可以放在ConcreteFlyweight中
    string _intrinsicState;
};
 
class ConcreteFlyweight:public Flyweight
{
public:
    //實現接口函數
    virtual void Operation(const string& extrinsicState);
    ConcreteFlyweight(string intrinsicState);
    ~ConcreteFlyweight();
};
 
class UnsharedConcreteFlyweight:public Flyweight
{
public:
    virtual void Operation(const string& extrinsicState);
    UnsharedConcreteFlyweight(string intrinsicState);
    ~UnsharedConcreteFlyweight();
};
 
class FlyweightFactory
{
public:
    FlyweightFactory();
    ~FlyweightFactory();
    //獲得一個請求的Flyweight對象
    Flyweight* GetFlyweight(string key);
    //獲取容器中存儲的對象數量
    void GetFlyweightCount();
protected:
private:
    //保存內部狀態對象的容器
    vector<Flyweight*> m_vecFly;
};
#endif


  • Flyweight.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "Flyweight.h"
#include <iostream>
 
using namespace std;
 
Flyweight::Flyweight(string intrinsicState)
{
    this->_intrinsicState = intrinsicState;
}
 
Flyweight::~Flyweight()
{}
 
string Flyweight::GetIntrinsicState()
{
    return this->_intrinsicState;
}
 
ConcreteFlyweight::ConcreteFlyweight(string intrinsicState):Flyweight(intrinsicState)
{
}
 
ConcreteFlyweight::~ConcreteFlyweight()
{
}
 
void ConcreteFlyweight::Operation(const string& extrinsicState)
{
    cout << this->GetIntrinsicState() << endl;
    cout << extrinsicState << endl;
}
 
UnsharedConcreteFlyweight::UnsharedConcreteFlyweight(string intrinsicState):Flyweight(intrinsicState)
{
}
 
UnsharedConcreteFlyweight::~UnsharedConcreteFlyweight()
{
}
 
void UnsharedConcreteFlyweight::Operation(const string& extrinsicState)
{
    cout << "extrinsicState" << endl;
}
 
FlyweightFactory::FlyweightFactory()
{}
 
FlyweightFactory::~FlyweightFactory()
{}
 
//若該對象已存在,直接返回,否則新建一個對象,存入容器中,再返回
Flyweight* FlyweightFactory::GetFlyweight(string key)
{
    vector<Flyweight*>::iterator iter = this->m_vecFly.begin();
    for(;iter!= this->m_vecFly.end();iter++)
    {
        if((*iter)->GetIntrinsicState() == key)
        {
            return *iter;
        }
    }
    Flyweight* fly = new ConcreteFlyweight(key);
    this->m_vecFly.push_back(fly);
    return fly;
}
 
void FlyweightFactory::GetFlyweightCount()
{
    cout << this->m_vecFly.size() << endl;
}


  • main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #include "Flyweight.h"
    #include <iostream>
    #include <string>
     
    using namespace std;
     
    int main()
    {
        //外部狀態extrinsicState
        string extrinsicState = "ext";
     
        //工廠對象,工廠對象
        FlyweightFactory* fc = new FlyweightFactory();
     
        //向工廠申請一個Flyweight對象,且該對象的內部狀態值爲“hello”
        Flyweight* fly = fc->GetFlyweight("hello");
     
        Flyweight* fly1 = fc->GetFlyweight("hello");
     
        //應用外部狀態
        fly->Operation(extrinsicState);
     
        fc->GetFlyweightCount();
     
        return 0;
    }


7、與其他模式的區別

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章