享元模式C++实现(flyweight)

2023-05-16

简介

在这里插入图片描述

动机

假设成立一个外包公司,主要给一些私营业主建网站。
商家客户都类似,要求也就是信息发布、产品展示、博客留言、论坛等功能。
各个客户要求差别不大,但客户数量多。
内部状态和外部状态

在享元对象内部并且不会随环境改变而改变的共享部分,可以成为是享元对象的内部状态。
随环境改变而改变的、不可以共享的状态就是外部状态。
享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据,如果能发现这些实例除了几个参数外基本都是相同的,有时就能大幅度减少需要实例化的类的数量。
如果能把那些参数移到类实例外面,在方法调用时将它们传递进来,就可以通过共享大幅度地减少单个实例的数目。

适用性

当以下情况成立时使用享元模式:
一个应用程序使用大量的对象,并且完全是由于使用大量的对象,造成很大的存储开销。
对象的大多数状态都可变为外部状态,并且如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
应用程序不依赖于对象表示。由于Flyweight对象可以被共享,对于概念上明显有别的对象,表示测试将返回真值。

结构

在这里插入图片描述

参与者

Flyweight
描述一个接口,通过这个接口Flyweight可以接受并作用于外部状态。
ConcreteFlyweight
实现Flyweight接口,并为内部状态增加空间。ConcreteFlyweight对象必须是可共享的。它所存储状态必须是内部的;即,它必须独立于ConcreteFlyweight的场景。
UnsharedConcreteFlyweight
并非所有的Flyweight子类都需要被共享。 Flyweight接口使共享成为可能,但它并不强制共享。
FlyweightFactory
创建并管理flyweight对象。
确保合理地共享flyweight。当用户请求一个flyweight时,Flyweight对象提供一个已创建的实例或者创建一个(如果不存在的话)。
Client
维持一个对flyweight的引用。
计算或存储一个(多个)flyweight的外部状态。
协作

Flyweight执行时所需状态必定是内部的或外部的。内部状态存储于ConcreteFlyweight对象之中;而外部对象则由Client对象存储或计算。当用户调用flyweight对象的操作时,将该状态传递给它。
用户不直接对ConcreteFlyweight类进行实例化,而只能从FlyweightFactory对象得到ConcreteFlyweight对象,这可以保证对它们适当地进行共享。

实例

假设成立一个外包公司,主要给一些私营业主建网站。商家客户要求的功能包括信息发布、产品展示、博客留言等功能。

共有a-j 10个客户,其中a-c客户需要信息发布,d-f需要产品展示,g-j客户需要博客功能。

利用享元模式模拟该公司建立网站,输出如下:

客户a: 信息发布

客户b:信息发布

。。。

网站分类总数为:3

UML
在这里插入图片描述

代码

在本次实验中:客户的号码就是外部状态,应该由专门的对象来处理,在这里简化为char类型的id。

另外注意没有UnsharedConcreteFlyweight类

Website类即Flyweight类

ConcreteWebsite类即ConcreteFlyweight类

#include<iostream>
#include<map>
#include<vector>
using namespace std;
 
/* 
假设成立一个外包公司,主要给一些私营业主建网站。商家客户要求的功能包括信息发布、产品展示、博客留言等功能。
共有a-j 10个客户,其中a-c客户需要信息发布,d-f需要产品展示,g-j客户需要博客功能。
利用享元模式模拟该公司建立网站,输出如下:
 
客户a: 信息发布
客户b:信息发布
。。。
 
网站分类总数为:3
 */
 
class Website{
public:
    virtual void Operation(char extrinsicstate) = 0;
};
 
class ConcreteWebsite: public Website {
public:
    ConcreteWebsite(string function){
        this->function = function;
    }
    void Operation(char extrinsicstate){
        cout<<"客户"<<extrinsicstate<<": "<<function<<endl;
    }
private:
    string function;
};
 
class FlyweightFactory{
private:
    map<string, ConcreteWebsite*> flyweights;
public:
    FlyweightFactory(){
        flyweights.insert(make_pair("信息发布", new ConcreteWebsite("信息发布")));
        flyweights.insert(make_pair("产品展示", new ConcreteWebsite("产品展示")));
        flyweights.insert(make_pair("博客功能", new ConcreteWebsite("博客功能")));
    }
    Website* GetFlyweight(string key){
        if(! flyweights.count(key)){
            flyweights.insert(make_pair(key, new ConcreteWebsite(key)));
            cout<<"添加状态: "<<key<<"成功"<<endl;
        }
        return (Website*) flyweights[key];
    }
    int getSize(){
        return flyweights.size();
    }
};
 
int main(){
    FlyweightFactory *factory = new FlyweightFactory();
    vector<Website*> pool;
    for(char i = 'a'; i <= 'j'; i++){
        Website *f;
        if(i >= 'a' && i <= 'c'){
            f = factory->GetFlyweight("信息发布");
            f->Operation(i);
        }else if(i >= 'd' && i <= 'f'){
            f = factory->GetFlyweight("产品展示");
            f->Operation(i);
        }else{
            f = factory->GetFlyweight("博客功能");
            f->Operation(i);
        }
        pool.push_back(f);
    }
    cout<<"网站分类总数为:"<<factory->getSize()<<endl;
    //if(pool[0] == pool[1])cout<<"THEY ARE THE SAME!"<<endl;
    return 0;
}

结果

在这里插入图片描述

总结

①本次实验掌握了享元模式的原理与方法,在选择flyweight时,要注意选择合适的享元类。

②按照实际情况分情况讨论具体的Flyweight类。

③不管建几个网站,只要是‘产品展示’,都是一样的,只要是‘博客’,也是完全相同的,但这样是有问题的,给企业建的网站不是一家企业,它们的数据不会相同,所以至少它们都应该有不同的账号(id值)。实际上这样写没有体现对象间的不同,只体现了它们共享的部分。

更多内容访问 omegaxyz.com
网站所有代码采用Apache 2.0授权
网站文章采用知识共享许可协议BY-NC-SA4.0授权
© 2019 • OmegaXYZ-版权所有 转载请注明出处

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

享元模式C++实现(flyweight) 的相关文章

  • PyQt5多线程刷新界面防假死

    在做GUI界面时我们希望后台任务能够与UI分开 xff0c 在PyQt中 xff0c 主线程用来重绘界面 而子线程里边的实时处理结果需要反馈到界面 xff0c 子线程里边不能执行界面更新操作 wxpython多线程刷新界面转到 http w
  • NSGA2算法中文详解与MATLAB实现整理

    NSGA2算法 NSGA II多目标遗传算法概述 http www omegaxyz com 2017 04 14 nsga iiintro NSGA2算法MATLAB实现 xff08 能够自定义优化函数 xff09 http www om
  • 对极大似然估计的理解

    参数估计 xff08 parameter estimation xff09 统计推断的一种 根据从总体中抽取的随机样本来估计总体分布中未知参数的过程 从估计形式看 xff0c 区分为点估计与区间估计 xff1a 从构造估计量的方法讲 xff
  • 动态规划——最大整除子集C++

    来自LeetCode 368 描述 给出一个由无重复的正整数组成的集合 xff0c 找出其中最大的整除子集 xff0c 子集中任意一对 Si xff0c Sj 都要满足 xff1a Si Sj 61 0 或 Sj Si 61 0 如果有多个
  • HyperVolume多目标评价指标概述

    提出 Hypervolume 指标评价方法最早是由 Zitzler 等提出 xff0c 它表示由解集中的个体与参考点在目标空间中所围成的超立方体的体积 评价标准 Hypervolume 指 标 评 价 方 法 是 一 种 与 Pareto
  • 三路快排C++实现与应用

    本文共467个字 xff0c 预计阅读时间需要2分钟 三路快排是快速排序算法的升级版 xff0c 用来处理有大量重复数据的数组 主要思想是选取一个key xff0c 小于key的丢到左边 xff0c 大于key的丢到右边 xff0c 递归实

随机推荐

  • Wilcoxon秩和检验简介与MATLAB实现

    Wilcoxon秩和检验 rank sum test xff0c 有时也叫Mann Whitney U检验 xff0c 是另一类非参数检验方法 xff0c 它们不对数据分布作特殊假设 xff0c 因而能适用于更复杂的数据分布情况 适用性 x
  • FatMouse’ Trade

    简介 贪心算法 xff08 又称贪婪算法 xff09 是指 xff0c 在对问题求解时 xff0c 总是做出在当前看来是最好的选择 也就是说 xff0c 不从整体最优上加以考虑 xff0c 他所做出的是在某种意义上的局部最优解 贪心算法不是
  • 算法复杂度与NP问题

    引言 美剧 基本演绎法 S2E2中 xff0c 两位研究 NP 问题的数学家被谋杀了 xff0c 凶手是同行 xff0c 因为被害者即将证明 P 61 NP 问题 假设人类证明了P 61 NP 是真的 xff0c 那么就会有一个算法 xff
  • 素数筛C++

    埃拉托斯特尼筛法 xff08 sieve of Eratosthenes xff09 是古希腊数学家埃拉托斯特尼发明的计算素数的方法 对于求解不大于n的所有素数 xff0c 我们先找出sqrt n 内的所有素数p1到pk xff0c 其中k
  • ubuntu安装mysql-server环境解决无穷依赖问题

    问题 ubuntu14 04 3安装mysql时报错 xff1a sudo apt get install mysql server mysql client 正在读取软件包列表 完成 正在分析软件包的依赖关系树 正在读取状态信息 完成 有
  • Levenshtein编辑距离C++实现

    简介 Levenshtein Distance是1965年由苏联数学家Vladimir Levenshtein发明的 Levenshtein Distance也被称为编辑距离 xff08 Edit Distance xff09 在信息论和计
  • 红黑树简介与C++应用

    简介 红黑树 xff08 Red Black Tree xff09 是一种自平衡二叉查找树 xff0c 是在计算机科学中用到的一种数据结构 xff0c 典型的用途是实现关联数组 它是在1972年由Rudolf Bayer发明的 xff0c
  • 碰撞域与广播域的区别

    在说到碰撞域 xff08 冲突域 xff09 和广播域之前 xff0c 首先要介绍一下三个网络互连设备 集线器 交换机和路由器 集线器 集线器是工作在物理层的设备 xff0c 当他收到数据以后就把这个数据复制复制以后就把这个数据象所有的接口
  • WordPress数据库error establishing a database connection错误

    本文共777个字 xff0c 预计阅读时间需要2分钟 作为一个买不起大型服务器只能用阿里云学生机的站长 xff0c 经常遇到error establishing a database connection错误 这是一种建立数据库连接时的错误
  • 基于稀疏大规模矩阵的多目标进化算法简介

    简介 可以看到本文的特色图片是个极度稀疏连接的神经网络 xff0c 它是由我们即将介绍论文中的算法SparseEA得到的 此篇论文是BIMK的田野 张兴义等人发表在IEEE Transactions on Evolutionary Comp
  • 回溯法——素数环C++实现

    本文共928个字 xff0c 预计阅读时间需要3分钟 回溯法简介 回溯法按深度优先策略搜索问题的解空间树 首先从根节点出发搜索解空间树 xff0c 当算法搜索至解空间树的某一节点时 xff0c 先利用剪枝函数判断该节点是否可行 xff08
  • Prime Path素数筛与BFS动态规划

    本文共2053个字 xff0c 预计阅读时间需要6分钟 BFS BFS xff0c 其英文全称是Breadth First Search BFS并不使用经验法则算法 从算法的观点 xff0c 所有因为展开节点而得到的子节点都会被加进一个先进
  • C++读取和写入文件(fstream等)

    本文共321个字 xff0c 预计阅读时间需要1分钟 2019年7月非常忙 xff0c 这大概是这个月的第一篇吧 某高校机试需要从文件中读取数据并将数据写入到文件中 完成这一操作需要用到fstream模块 xff0c 网上一堆资料 xff0
  • 并查集应用——PAT甲级2019春季

    并查集适用问题举例 1 已知 xff0c 有n个人和m对好友关系 2 如果两个人是直接的或者间接的好友 xff08 好友的好友的好友 xff09 xff0c 那么他们属于一个集合 xff0c 就是一个朋友圈中 3 写出程序 xff0c 求这
  • 抽象工厂模式与单件模式C++混合实现

    抽象工厂 当每个抽象产品都有多于一个的具体子类的时候 xff0c 工厂角色怎么知道实例化哪一个子类呢 xff1f 比如每个抽象产品角色都有两个具体产品 抽象工厂模式提供两个具体工厂角色 xff0c 分别对应于这两个具体产品角色 xff0c
  • source命令自动运行terminal的指令

    source命令也称为 点命令 xff0c 也就是一个点符号 xff08 xff09 source命令通常用于重新执行刚修改的初始化文件 xff0c 使之立即生效 xff0c 而不必注销并重新登录 用法 xff1a source filen
  • 适配器模式C++实现

    本文共916个字 xff0c 预计阅读时间需要3分钟 简介 适配器模式 xff1a 将一个类的接口转换成客户希望的另一个接口 适配器模式让那些接口不兼容的类可以一起工作 适配器模式的别名为包装器 Wrapper 模式 xff0c 它既可以作
  • 装饰模式C++实现

    简介 动态地给一个对象添加一些额外的职责 就增加功能来说 xff0c 装饰模式比生成子类更为灵活 动机 有时我们希望给某个对象而不是整个类添加一些功能 使用继承机制是添加功能的一种有效途径 xff0c 但不够灵活 xff0c 用户不能控制对
  • 软件测试——测试计划

    完整版 xff08 包括表格和图片 xff09 请访问 xff1a http www omegaxyz com 2019 08 02 software testing 本文共6034个字 xff0c 预计阅读时间需要16分钟 文章目录 1简
  • 享元模式C++实现(flyweight)

    简介 动机 假设成立一个外包公司 xff0c 主要给一些私营业主建网站 商家客户都类似 xff0c 要求也就是信息发布 产品展示 博客留言 论坛等功能 各个客户要求差别不大 xff0c 但客户数量多 内部状态和外部状态 在享元对象内部并且不