富阳网站设计,大丰建站,设计师招聘平台,永州网站网站建设1.定义 享元模式是一种结构型设计模式#xff0c; 它允许你在消耗少量内存的情况下支持大量对象。
2.滑滑梯问题 在说明亨元模式之前#xff0c;我们先看看关于滑滑梯的程序设计。小区的楼下只有三个滑滑梯#xff0c;但是想玩的小朋友却非常多。怎么设计计滑滑梯资源的管理…1.定义 享元模式是一种结构型设计模式 它允许你在消耗少量内存的情况下支持大量对象。
2.滑滑梯问题 在说明亨元模式之前我们先看看关于滑滑梯的程序设计。小区的楼下只有三个滑滑梯但是想玩的小朋友却非常多。怎么设计计滑滑梯资源的管理避免小朋友使用滑滑梯的时发生冲突呢。(这里我们设定每个滑滑梯每次仅能供一个小朋友玩耍)。解决这个问题我们就可以使用享元模式(Flyweight)它就是运用共享技术有效的支持大量细粒度的对象。 怎么理解大量细粒度的对象呢我一开始理解亨元模式的时候其实对这个概念理解的并不清楚。就滑滑梯这个问题大家认为大量细粒度对象是滑滑梯还是小朋友呢如果这个问题回答的不好那么说明你对亨元模式还是不够了解。这里我直接给出答案大量细粒度的对象指的是滑滑梯。有朋友会很疑惑滑滑梯我们不是设定有三个么怎么是大量细粒度对象哪儿来的大量。其实这个问题逻辑很简单我们假设有一百个小朋友要玩滑滑梯那事实上我们只要造一百个滑滑梯就好了对么。但现实是我们并没有那么蠢我们让小朋友排着队轮流玩就好了。三个滑滑梯事实上是果是采用了亨元模式的果已经是亨元模式优化过的情况。如果没有亨元模式那么我们确实要造一百个滑滑梯每个小朋友专属一个。
3.实现思路 如果不对滑滑梯的资源进行管理可能会出现这个情况小朋友们在使用滑滑梯时并考虑当前滑滑梯是否被使用。很可能两个小朋友同时使用一个滑滑梯导致冲突不符合预期。所以我们重点是要对滑滑梯的资源使用进行有效的管理比如这时候有一个大人来维护滑滑梯的使用秩序。大人作为三个滑滑梯的管理员小朋友们使用滑滑梯需要向他提出申请得到准许之后才能玩。经过大人管理之后的滑滑梯使用会变成这个情况小朋友们排队申请滑滑梯的使用权限大人根据滑滑梯的现有使用状况如果还有滑滑梯上没有小朋友玩耍那么可以提供该滑滑梯给小朋友如果滑滑梯全部被使用则小朋友申请资源失败需要继续等待。 我们进一步假设加入这时候小区其实存在若干个备用的充气滑滑梯而且小区虽然有一百个小朋友但他们并不是同时都在楼下玩的。这个时候整个系统就是一个动态的过程。只要有小朋友申请玩滑滑梯管理员有限在现有的滑滑梯资源里找如果有空闲的滑滑梯就会提供给当前申请的小朋友如果没有那么就(新建资源)使用备用的充气滑滑梯。如果连备用的充气滑滑梯都用完了这就已经触及到系统的资源上限了(内存上限)还是需要排队。 总而言之恒元模式就是解决需要为一个小朋友定制一个滑滑梯的问题。通过共享资源池来达到相同的目的。
4.组成结构
抽象享元为具体享元角色规定了必须实现的方法而外部状态就是以参数的形式通过此方法传入。(滑滑梯)具体享元实现抽象角色规定的方法。如果存在内部状态就负责为内在部状态提供存储空间。(社区里具体的滑滑梯)享元工厂角色负责创建和管理享元角色。要想达到共享的目的这个角色的实现是关键(管理员)客户端角色维护对所有享元对象的引用而且还需要存储对应的外部状态。 (小朋友)
内部状态就是各个对象不会随着环境的改变而改变的可共享部分;滑梯本身
外部状态指对象随环境改变而改变的不可以共享的部分。内部状态和外部状态彼此互不影响改变其中一个并不会改变另一个的行为。(滑梯使用者)。
享元模式将享元对象的状态外部化而读取外部状态可能使得运行时间稍微变长。
5.示例代码
#include iostream
#includestring
#includemap
using namespace std;//客户端类
class Kid
{
private:string m_name;
public:Kid(string name){m_name name;}std::string GetName(){return m_name;}
};//抽象亨元类(滑滑梯)
class Slide
{
public:virtual ~Slide() default;virtual void Use(Kid user) 0;
};//具体亨元类(小区的滑滑梯)
class ConcreteSlide :public Slide
{
private:string m_id;
public:ConcreteSlide(std::string id){m_id id;}void Use(Kid user)override{cout 滑滑梯 m_id 小朋友 user.GetName() endl;}
};//滑滑梯管理员
//如果存在则提供给客户如果不存在的话则创建一个新的享元对象。
class SlideFactory
{
private:std::mapstd::string, Slide* flyweights;
public:~SlideFactory(){for (auto it flyweights.begin(); it ! flyweights.end(); it)delete it-second;}Slide* GetSlideCategory(string key){for (auto it flyweights.begin(); it ! flyweights.end(); it){if (it-first key)return it-second;}Slide* slide new ConcreteSlide(key);flyweights.insert(pairstd::string, Slide*(key, slide));return slide;}int GetSlideCount(){return flyweights.size();}
};int main()
{SlideFactory f;Slide* fx f.GetSlideCategory(一号滑梯);fx-Use(Kid(奇奇));Slide* fy f.GetSlideCategory(二号滑梯);fy-Use(Kid(天天));Slide* fz f.GetSlideCategory(三号滑梯);fz-Use(Kid(甜甜));Slide* fl f.GetSlideCategory(一号滑梯);fl-Use(Kid(嘟嘟));Slide* fm f.GetSlideCategory(二号滑梯);fm-Use(Kid(豆芽));Slide* fn f.GetSlideCategory(三号滑梯);fn-Use(Kid(年年));cout 得到滑滑梯总数 f.GetSlideCount() endl;system(pause);return 0;
}
6.引用
C设计模式 - 享元模式 - 知乎 (zhihu.com)
C设计模式——享元模式 - 冰糖葫芦很乖 - 博客园 (cnblogs.com)