设计模式 -- 享元模式(Flyweight Pattern)

2023-10-29

使用共享对象可以有效的支持大量的细粒度对象。

应用场景

主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。例如:缓存,对象池;Android中: Message.obtain通过重用Message对象来避免大量的Message对象被频繁的创建和销毁。

FlyWeightFactory负责创建和管理享元单元,当一个客户端请求时,工厂需要检查当前对象池中是否有符合条件的对象,如果有,就返回已经存在的对象,如果没有,则创建一个新对象,FlyWeight是超类。

享元模式的主要角色有如下:

  • 抽象享元角色(Flyweight):是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。

  • 具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。

  • 非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。

  • 享元工厂(Flyweight Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。

//棋盘
class Chessboard extends MouseAdapter {
    WeiqiFactory wf;
    Graphics g;

    Chessboard() {
        wf = new WeiqiFactory();
        g = CenterJP.getGraphics();
    }

    public void mouseClicked(MouseEvent e) {
        Point pt = new Point(e.getX() - 15, e.getY() - 15);
        if (wz.isSelected()) {
            ChessPieces c1 = wf.getChessPieces("w");
            c1.DownPieces(g, pt);
        } else if (bz.isSelected()) {
            ChessPieces c2 = wf.getChessPieces("b");
            c2.DownPieces(g, pt);
        }
    }
}


//抽象享元角色:棋子
interface ChessPieces {
    public void DownPieces(Graphics g, Point pt);    //下子
}


//具体享元角色:白子
class WhitePieces implements ChessPieces {
    public void DownPieces(Graphics g, Point pt) {
        g.setColor(Color.WHITE);
        g.fillOval(pt.x, pt.y, 30, 30);
    }
}


//具体享元角色:黑子
class BlackPieces implements ChessPieces {
    public void DownPieces(Graphics g, Point pt) {
        g.setColor(Color.BLACK);
        g.fillOval(pt.x, pt.y, 30, 30);
    }
}


//享元工厂角色
class WeiqiFactory {
    private ArrayList<ChessPieces> qz;

    public WeiqiFactory() {
        qz = new ArrayList<ChessPieces>();
        ChessPieces w = new WhitePieces();
        qz.add(w);
        ChessPieces b = new BlackPieces();
        qz.add(b);
    }

    public ChessPieces getChessPieces(String type) {
        if (type.equalsIgnoreCase("w")) {
            return (ChessPieces) qz.get(0);
        } else if (type.equalsIgnoreCase("b")) {
            return (ChessPieces) qz.get(1);
        } else {
            return null;
        }
    }
}

Android中SQLiteCompiledSql的使用,其实是很多数据库系统典型的实现。从应用启动,通过各种数据库操作,我们不知道进行了多少次的查询操作,而这些操作中又有相当一部分sql语句是相同的,这些编译后的sql编译对象其实是一样的,是可以共用共享的,其实就是缓存。SQLiteCompiledSql就是这样的一个需要共享的享元对象。其中SqliteDatabase中的mCompiledQuerie就是存放享元对象的容器。通过这种方式大大减少了sql编译对象的创建,提高了数据库操作的性能。


根据以下文章总结:

  1. Java设计模式:23种设计模式全面解析(超级详细)HYPERLINK http://c.biancheng.net/design_pattern/ 

  2. 3种设计模式详解 https://www.iteye.com/blog/zz563143188-1847029 

  3. Android系统编程思想:设计模式https://github.com/sucese/android-open-source-project-analysis/blob/master/doc/Android%E7%B3%BB%E7%BB%9F%E8%BD%AF%E4%BB%B6%E8%AE%BE%E8%AE%A1%E7%AF%87/02Android%E7%B3%BB%E7%BB%9F%E8%BD%AF%E4%BB%B6%E8%AE%BE%E8%AE%A1%E7%AF%87%EF%BC%9A%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F.md#35-%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F

  4. 设计模式 https://blog.csdn.net/shusheng0007/category_8638565.html

  5. java设计模式 https://blog.csdn.net/qq_37909508/category_8976362.html

  6. 设计模式 https://www.cnblogs.com/zuoxiaolong/category/509144.html 

  7. 设计模式 在源码中的应用 https://blog.csdn.net/qq_36970993/category_10620886.html

  8. Android系统设计中存在设计模式分析 https://www.2cto.com/kf/201208/150650.html

  9. Android设计模式系列 - 基于android的各种代码分析各种设计模式 https://www.cnblogs.com/qianxudetianxia/category/312863.html 

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

设计模式 -- 享元模式(Flyweight Pattern) 的相关文章

  • 数据库-ER建模

    目录 基本概念 1 实体 entity 2 属性 attribute 3 联系 relation 3 1 基数约束的四种形态 3 1 1 基数约束形态一 3 1 2 基数约束形态二 3 1 3 基数约束形态三 3 1 4 基数约束形态四 扩

随机推荐

  • OneOS文字转语言组件实操

    本文分享自中移OneOS微信公众号 当万耦遇上chaoTTS 作者 柏灵 大家好 柏灵又又又来啦 相信大家已经开始在寒冷的冬季种植鲜嫩的豌豆尖 火锅里烫上豌豆尖 从此打工人有了豌豆尖自由 还没有种植的小伙伴 可以通过OneOS 基于端云融合
  • fit、transform、fit_transform的区别,为什么训练集用 fit_transform , 测试集用 transform

    三个函数的使用具体解释 在数据预处理中的应用 1 只涉及一组数据 fit data 对数据进行拟合 获得了数据的均值 最大最小 标准差等属性值 transform data 利用 fit data 获取到的属性对数据做预处理 如标准化 归一
  • cocos cretor shader effect-the book of shader前言

    前言 说来惭愧 半年前开始接触cocso creator shader的时候 看了官方教程 看了大神写的例子 搞懂了一些语法概念 可是当时看一遍有种似懂非懂的感觉 那种感觉就是听过很多道理 任然过不好一生 在cocos论坛里有大神也分享过自
  • Foxmail 搜索功能找不到全部邮件问题的解决方法。

    经常使用Foxmail办公收发邮件 发现Foxmail 搜索功能找不到全部邮件 原来问题出在搜索上 举例说明 迁移到Foxmail后 王卡卡同志给我发过3封邮件 可是我用据称无比强大的Foxmail搜索邮件时 输入关键字 root 只能找到
  • [计算机毕业设计]数字水印算法

    前言 大四是整个大学期间最忙碌的时光 一边要忙着准备考研 考公 考教资或者实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的毕设项目越来越难 有不少课题是研究生级别难度的 对本科同学来说是充满挑战 为帮助大
  • 梦幻模拟战pc版更新服务器正在维护,梦幻模拟战PC版免CD(更新2代跳出补丁 一些实用说明)...

    最近看到游侠有发梦幻模拟战PC版1 2 下载 不过要禁用DX 还要拔光驱 比较麻烦 我把我以前收藏的L1 L2 免CD发出来分享 我自己反正测试可以用 1代 第1步 替换langpc exe 请做好备份 第2步 复制光盘上 DISK1 ID
  • shell脚本中$!、$@、$#、$$、$0、$1、$2、$*的含义

    一 shell脚本中 0 1 2 的含义 Shell最后运行的后台Process的PID 后台运行的最后一个进程的进程ID号 添加到shell当中参数的个数 Shell本身的PID ProcessID 即脚本运行的当前进程ID号 0 脚本本
  • 【第八章 线程的同步机制(同步代码块、同步方法)】

    第八章 线程的同步机制 同步代码块 同步方法 1 线程的同步机制方式一 同步代码块 java中通过同步机制解决线程安全问题 synchronized 同步监视器 需要被同步的代码 说明 操作共享数据的代码即为需要被同步的代码 共享数据 多个
  • 关于浏览器静止音频自动播放的问题

    背景 今天在制作前端页面时 想要给网页加上会自动播放的音乐 但是用audio标签设置音频的自动播放后 即使将autoplay属性设置成true 谷歌等浏览器页面加载完成后也不会自动播放音乐 尝试了各种办法无果 原因 目前 最为流行的浏览器共
  • 求助TCanvas内存无限涨的问题

    求助TCanvas内存无限涨的问题 Delphi Windows SDK API http www delphi2007 net DelphiMultimedia html delphi 20061110220830160 html pro
  • 利用Wireshark分析TCP三次握手

    首先打开 http www baidu com这个网址进行抓包 首先在过滤器中输入 http过滤 找到 GET HTTP 1 1 我们可以看到在出现了三条TCP记录之后才出现了HTTP这也更加相信HTTP是基于TCP协议的 第一次TCP握手
  • uniapp 顶部头部样式

  • 【Python】剑指offer 14:剪绳子

    题目 给你一根长度为n的绳子 请把绳子剪成m段 m和n都是整数 n gt 1并且m gt 1 每段绳子的长度记为k 0 k 1 k m 请问k 0 k 1 k m 可能的最大乘积是多少 例如 当绳子的长度为8时 我们把它剪成长度分别为2 3
  • idea中类存在编译器报错类无法找到,打包正常解决

    步骤 关键在于清掉类在idea的cache 1 刷新maven项目 2 清理idea缓存 3 maven clean install 4 重新bulid 5 如果使用了lombok插件开启之后重新build 6 maven依赖冲突导致
  • Gin微服务框架_golang web框架_完整示例Demo

    Gin简介 前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住分享一下给大家 点击跳转到网站 Gin是一个golang的微框架 封装比较优雅 API友好 源码注释比较明确 具有快速灵活 容错方便等特点 其实对于golang而
  • Haystack 太强了!存 2600 亿图片

    作者 奇伢 来源 奇伢云存储 小文件存储 小文件存储 老生常谈的问题 先聊聊小文件存储重点关注的是什么 以前我们提过 对于磁盘来说 小 io 吃 iops 大块 io 吃吞吐 划重点 小文件的重点是 io 次数 为什么每次提到海量小文件的时
  • 定时器串口收发和空闲中断串口收发+STM32CubeMX

    引言 最近在做串口实验 总结了两种串口收发的方法 第一种是用定时器定的 第二种是使用空闲中断 第一种 使用定时器 具体做法是在串口接收数据时启动定时器 每接收一帧数据要复位定时值以保证定时器不会溢出 根据波特率计算出大概什么时候接收数据完成
  • 保姆级别uni-app使用低功耗蓝牙

    实现方式 本文使用 uni app Vue3 的方式进行开发 以手机app的方式运行 uni app 提供了低功耗蓝牙 的 api 和微信小程序提供的 api 是一样的 所以本文的讲解也适用于微信小程序 本文参考文档 https blog
  • 普中51单片机独立按键原理及源代码

    由于按键是机械弹性按键 具有弹性 在毫秒级别的时间下 按键后有短暂的抖动 转载自江科大自协化51单片机入门教程 如果按键一次用力较轻 按键里的小金属片可能会多次抖动 使得LED闪烁多次 即轻微按一次 小概率出现多次LED闪烁 消除毫秒级别下
  • 设计模式 -- 享元模式(Flyweight Pattern)

    使用共享对象可以有效的支持大量的细粒度对象 应用场景 主要目的是实现对象的共享 即共享池 当系统中对象多的时候可以减少内存的开销 通常与工厂模式一起使用 例如 缓存 对象池 Android中 Message obtain通过重用Messag