- Published on
设计模式(11)——享元 Flyweight
- Authors
- Name
- Leon
十一、Flyweight(享元模式,对象结构型模式)
1. 意图:
运用共享技术有效地支持大量细粒度的对象。
2. 适用:
Flyweight 模式的有效性很大程度上取决于如何使用它以及在何处使用它。当以下情况都成立时使用 Flyweight 模式。
- 一个应用程序使用了大量的对象。
- 完全由于使用大量的对象,造成很大的存储开销。
- 对象的大多数状态都可变为外部状态。
- 如果删除对象的外部状态,那么可以用相对校少的共享对象取代很多组对象。
- 应用程序不依赖于对象标识。由于 Flyweight 对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
3. 类图:
4. 中间层思考:
享元模式在系统和直接使用细粒度对象之间加入一个享元工厂,这个工厂就是中间层。系统不再直接创建和使用对象,而是由这个工厂来负责创建对象,工厂内部对同一对象只会创建一次,保证对象都是共享的。
5. Flyweight 与 简单工厂
享元模式与简单工厂模式有点像,都用到了工厂的概念。其实享元模式里面就是用到了简单工厂模式来管理细粒度对象。享元模式解决的问题是对象的共享,而工厂模式解决的问题是如何封装对象的创建过程。明白它们两解决的问题,就知道它们是两种完全不一样的模式。但是它们却可以完美地结合在一起,协同解决问题。
6. C++实现:
- 先编写一个
Flyweight
类,构造函数接收一个参数instrinsicState
用于描述内部状态(不变部分) - 包含一个函数
Operation(const string& extrinsicState)
用于操作外部状态(可变部分) - 编写
Flyweight
的子类ConcreteFlyweight
- 编写工厂类
FlyweightFactory
, 包含一个函数GetFlyweight(const string& key)
, 一个vector<Flyweight*> _fly
用于存储已创建的Flyweight
Flyweight.h
// Flyweight.h
#pragma once
#include <string>
using namespace::std;
class Flyweight {
public:
virtual ~Flyweight();
virtual void Operation(const string& extrinsicState);
string GetIntrinsicState();
protected:
Flyweight(string intrinsicState);
private:
string _intrinsicState;
};
class ConcreteFlyweight : public Flyweight {
public:
ConcreteFlyweight(string intrinsicState);
~ConcreteFlyweight();
void Operation(const string& extrinsicState);
protected:
private:
};
Flyweight.cpp
//Flyweight.cpp
#include "Flyweight.h"
#include <iostream>
using namespace::std;
Flyweight::Flyweight(string intrinsicState) {
this->_intrinsicState = intrinsicState;
}
Flyweight::~Flyweight() {}
void Flyweight::Operation(const string& extrinsicState){}
string Flyweight::GetIntrinsicState() {
return this->_intrinsicState;
}
ConcreteFlyweight::ConcreteFlyweight(string intrinsicState) : Flyweight(intrinsicState) {
cout << "ConcreteFlyweight Build..." << intrinsicState << endl;
}
ConcreteFlyweight::~ConcreteFlyweight() {}
void ConcreteFlyweight::Operation(const string& extrinsicState) {
cout << "ConcreteFlyweight: 内蕴 [" << this->GetIntrinsicState() << "] 外蕴 [" << extrinsicState << "]" << endl;
}
FlyweightFactory.h
//FlyweightFactory.h
#pragma once
#include "Flyweight.h"
#include <string>
#include <vector>
using namespace::std;
class FlyweightFactory {
public:
FlyweightFactory();
~FlyweightFactory();
Flyweight* GetFlyweight(const string& key);
protected:
private:
vector<Flyweight*> _fly;
};
FlyweightFactory.cpp
//FlyweightFactory.cpp
#include "FlyweightFactory.h"
#include <iostream>
#include <string>
#include <cassert>
using namespace::std;
FlyweightFactory::FlyweightFactory() {}
FlyweightFactory::~FlyweightFactory() {}
Flyweight* FlyweightFactory::GetFlyweight(const string& key) {
vector<Flyweight*>::iterator it = _fly.begin();
for (; it != _fly.end(); it++) {
//找到了,就一起用
if ((*it)->GetIntrinsicState() == key) {
cout << "already created by users..." << endl;
return *it;
}
}
Flyweight* fw = new ConcreteFlyweight(key);
_fly.push_back(fw);
return fw;
}
main.cpp
//main.cpp
#include "Flyweight.h"
#include "FlyweightFactory.h"
#include <iostream>
using namespace::std;
int main(int argc, char* argv[]) {
FlyweightFactory* fc = new FlyweightFactory();
Flyweight* fw1 = fc->GetFlyweight("hello");
Flyweight* fw2 = fc->GetFlyweight("world!");
Flyweight* fw3 = fc->GetFlyweight("hello");
return 0;
}