首页 > 代码库 > 设计模式之十三:Flyweight(享元)—对象结构型模式

设计模式之十三: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、与其他模式的区别




来自为知笔记(Wiz)