赞
踩
作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
享元模式是一种结构型的软件设计模式,通过共享对象的方式,尽可能减少内存占用,从而达到优化的目的。
就像打麻将,同时有10桌在玩,每桌都有4个"八筒",如果建立40个"八筒"对象,那就非常冗余,但如果用享元模式建立一套麻将牌,每桌打出"八筒"时,就调用享元中的"八筒",相当于只用了1个对象,这样即节省了资源,也完成了需求。
上述例子中,桌号和牌号就是享元模式的外蕴状态,如A1八筒,就是A桌的第一个"八筒",A和1是外蕴状态;而卡牌"八筒"本身就是内蕴状态,内蕴是可以共享的。外蕴随环境变化,占用资源也少的多,往往只是简单的数据结构。
享元模式的优点:
享元模式的缺点:
客户端即Main主函数,调用享元工厂获取享元对象。
场景描述:模拟组合一套八卦牌。
- //Flyweight.h
- /****************************************************/
- #pragma once
- #include <iostream>
- #include <unordered_map>
- #include <vector>
- #include <list>
-
- using namespace std;
-
- // 抽象享元
- class Flyweight
- {
- public:
- // 操作
- virtual void operation() = 0;
-
- };
-
- // 具体享元
- class ConcreteFlyweight : public Flyweight
- {
- public:
- // 构造函数
- ConcreteFlyweight(string name) : m_name(name) {}
-
- // 操作
- virtual void operation() {
- cout << "打出" << m_name << endl;
- }
-
- private:
- string m_name;
- };
-
- // 享元工厂
- class FlyweightFactory
- {
- public:
- // 析构函数
- ~FlyweightFactory() {
- for (auto it : flyweights) {
- cout << "销毁" << it.first << "牌" << endl;
- delete it.second;
- it.second = nullptr;
- }
- flyweights.clear();
- }
-
- // 获取享元
- Flyweight* getFlyweight(string name) {
- // 若没有,则创建
- if (flyweights.find(name) == flyweights.end()) {
- cout << "创建" << name << "牌" << endl;
- flyweights[name] = new ConcreteFlyweight(name);
- }
- else {
- cout << "已有" << name << "牌" << endl;
- }
- return flyweights[name];
- }
-
- private:
- std::unordered_map<string, Flyweight*> flyweights;
- };
- //main.cpp
- /****************************************************/
- #include <iostream>
- #include <string>
- #include "Flyweight.h"
-
- using namespace std;
-
- int main()
- {
- FlyweightFactory *factory = new FlyweightFactory();
- Flyweight* f1 = factory->getFlyweight("乾");
- Flyweight* f2 = factory->getFlyweight("坤");
- Flyweight* f3 = factory->getFlyweight("坎");
- Flyweight* f4 = factory->getFlyweight("离");
- Flyweight* f5 = factory->getFlyweight("震");
- Flyweight* f6 = factory->getFlyweight("巽");
- Flyweight* f7 = factory->getFlyweight("艮");
- Flyweight* f8 = factory->getFlyweight("兑");
- Flyweight* f9 = factory->getFlyweight("坤");
- f3->operation();
- delete factory;
- factory = nullptr;
- return 0;
- }
程序结果如下。
八卦的八个牌在初次调用时因为不存在所以创建,而第九次调用已有的坤,便不用new了。删除工厂后,析构函数别忘了将new的数据delete。
我尽可能用较通俗的话语和直观的代码例程,来表述我对享元模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解享元模式。
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。