作者按:《每天一个设计模式》旨在初步领会设计模式的精髓,目前采用javascriptpython两种语言实现。诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :)

个人技术博客-godbmw.com 欢迎来玩! 每周至少 1 篇原创技术分享,还有开源教程(webpack、设计模式)、面试刷题(偏前端)、知识整理(每周零碎),欢迎长期关注!本篇博客地址是:《每天一个设计模式之享元模式》。

如果您也想进行知识整理 + 搭建功能完善/设计简约/快速启动的个人博客,请直接戳theme-bmw

0. 项目地址

  • 享元模式·代码
  • 《每天一个设计模式》地址

1. 什么是“享元模式”?

享元模式:运用共享技术来减少创建对象的数量,从而减少内存占用、提高性能。

  1. 享元模式提醒我们将一个对象的属性划分为内部和外部状态

    • 内部状态:可以被对象集合共享,通常不会改变
    • 外部状态:根据应用场景经常改变
  2. 享元模式是利用时间换取空间的优化模式。

2. 应用场景

享元模式虽然名字听起来比较高深,但是实际使用非常容易:只要是需要大量创建重复的类的代码块,均可以使用享元模式抽离内部/外部状态,减少重复类的创建。

为了显示它的强大,下面的代码是简单地实现了大家耳熟能详的“对象池”,以彰显这种设计模式的魅力。

3. 代码实现

这里利用pythonjavascript实现了一个“通用对象池”类--ObjectPool。这个类管理一个装载空闲对象的数组,如果外部需要一个对象,直接从对象池中获取,而不是通过new操作

对象池可以大量减少重复创建相同的对象,从而节省了系统内存,提高运行效率。

为了形象说明“享元模式”在“对象池”实现和应用,特别准备了模拟了File类,并且模拟了“文件下载”操作。

通过阅读下方代码可以发现:对于File类,内部状态是pool属性和download方法;外部状态是namesrc(文件名和文件链接)。借助对象池,实现了File类的复用。

注:为了方便演示,Javascript实现的是并发操作,Python实现的是串行操作。输出结果略有不同。

3.1 Python3 实现

from time import sleepclass ObjectPool:  # 通用对象池def __init__(self):self.__pool = []# 创建对象def create(self, Obj):# 对象池中没有空闲对象,则创建一个新的对象# 对象池中有空闲对象,直接取出,无需再次创建return self.__pool.pop() if len(self.__pool) > 0 else Obj(self)# 对象回收def recover(self, obj):return self.__pool.append(obj)# 对象池大小def size(self):return len(self.__pool)class File:  # 模拟文件对象def __init__(self, pool):self.__pool = pooldef download(self):  # 模拟下载操作print('+ 从', self.src, '开始下载', self.name)sleep(0.1)print('-', self.name, '下载完成')# 下载完毕后,将对象重新放入对象池self.__pool.recover(self)if __name__ == '__main__':obj_pool = ObjectPool()file1 = obj_pool.create(File)file1.name = '文件1'file1.src = 'https://download1.com'file1.download()file2 = obj_pool.create(File)file2.name = '文件2'file2.src = 'https://download2.com'file2.download()file3 = obj_pool.create(File)file3.name = '文件3'file3.src = 'https://download3.com'file3.download()print('*' * 20)print('下载了3个文件, 但其实只创建了', obj_pool.size(), '个对象')

输出结果(这里为了方便演示直接使用了sleep方法,没有再用多线程模拟):

+ 从 https://download1.com 开始下载 文件1
- 文件1 下载完成
+ 从 https://download2.com 开始下载 文件2
- 文件2 下载完成
+ 从 https://download3.com 开始下载 文件3
- 文件3 下载完成
********************
下载了3个文件, 但其实只创建了 1 个对象

3.2 ES6 实现

// 对象池
class ObjectPool {constructor() {this._pool = []; //}// 创建对象create(Obj) {return this._pool.length === 0? new Obj(this) // 对象池中没有空闲对象,则创建一个新的对象: this._pool.shift(); // 对象池中有空闲对象,直接取出,无需再次创建}// 对象回收recover(obj) {return this._pool.push(obj);}// 对象池大小size() {return this._pool.length;}
}// 模拟文件对象
class File {constructor(pool) {this.pool = pool;}// 模拟下载操作download() {console.log(`+ 从 ${this.src} 开始下载 ${this.name}`);setTimeout(() => {console.log(`- ${this.name} 下载完毕`); // 下载完毕后, 将对象重新放入对象池this.pool.recover(this);}, 100);}
}/****************** 以下是测试函数 **********************/let objPool = new ObjectPool();let file1 = objPool.create(File);
file1.name = "文件1";
file1.src = "https://download1.com";
file1.download();let file2 = objPool.create(File);
file2.name = "文件2";
file2.src = "https://download2.com";
file2.download();setTimeout(() => {let file3 = objPool.create(File);file3.name = "文件3";file3.src = "https://download3.com";file3.download();
}, 200);setTimeout(() =>console.log(`${"*".repeat(50)}\n下载了3个文件,但其实只创建了${objPool.size()}个对象`),1000
);

输出结果如下:

+ 从 https://download1.com 开始下载 文件1
+ 从 https://download2.com 开始下载 文件2
- 文件1 下载完毕
- 文件2 下载完毕
+ 从 https://download3.com 开始下载 文件3
- 文件3 下载完毕
**************************************************
下载了3个文件,但其实只创建了2个对象

4. 参考

  • 《JavaScript 设计模式和开发实践》

转载于:https://www.cnblogs.com/geyouneihan/p/10148677.html

每天一个设计模式之享元模式相关推荐

  1. 北风设计模式课程---享元模式

    北风设计模式课程---享元模式 一.总结 一句话总结: 不仅要通过视频学,还要看别的博客里面的介绍,搜讲解,搜作用,搜实例 1.享元模式的本质是什么? 池技术:各种缓存池都是享元模式的体现 说到享元模 ...

  2. python设计模式之享元模式

    一.享元模式定义: 享元模式是一种用于解决资源和性能压力时会使用到的设计模式,它的核心思想是通过引入数据共享来提升性能. 在开发3D游戏时,例如有成千上万的士兵或者有成千上万棵树,如果一个3D地带的每 ...

  3. 北风设计模式课程---享元模式与单例模式区别

    北风设计模式课程---享元模式与单例模式区别 一.总结 一句话总结: 不仅要通过视频学,还要看别的博客里面的介绍,搜讲解,搜作用,搜实例 1.享元模式与单例模式区别? 级别:单例模式是类级别的,一个类 ...

  4. Java设计模式之享元模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

  5. 详解设计模式:享元模式

    享元模式(Flyweight Pattern),是对象池的一种体现,也是 GoF 的 23 种设计模式中的一种结构型设计模式. 享元模式 主要用于减少创建对象的数量,以减少内存占用和提高性能.它提供了 ...

  6. 设计模式之享元模式详解

    设计模式之享元模式详解 概述 享元模式定义: ​ 运用共享技术来有效地支持大量细粒度对象的复用.它==通过共享已经存在的对象来大幅度减少需要创建的对象数量==.避免大量相似对象的开销,从而提高系统资源 ...

  7. 【设计模式】享元模式(C#)

    [设计模式]享元模式 1.概述 Flyweight Design Pattern,结构型模式.享元模式中的"享元"指被共享的单元.享元模式通过复用对象,以达到节省内存的目的. 用于 ...

  8. Java设计模式之享元模式

    Java设计模式之享元模式 1. 享元模式概述 1.1 享元定义 1.2 享元模式注意事项 2. 享元模式实现 1. 享元模式概述 1.1 享元定义 1)享元模式(享元模式)也叫蝇量模式:利用共享技术 ...

  9. .net设计模式 (享元模式)学习笔记

    运用设计模式只是为了解决一类问题的,当解决掉当前一类问题,通常会在解决这个问题时候 带来其他问题  合理应用扬长避短 结构性设计模式:关注的是类与类之间的关系 .net设计模式 (享元模式)学习笔记 ...

最新文章

  1. LeetCode简单题之旋转字符串
  2. matlab 实现 stacked Autoencoder 解决图像分类问题
  3. angularjs mysql_AngularJS SQL
  4. 如何设置MongoDB快捷启动?
  5. 子元素div高度不确定时父div高度如何自适应
  6. 学习笔记04:《产品经理白皮书》
  7. C#编写WINNT服务,随便解决安卓开发遇到的5037被众多程序无节操占用的问题
  8. 假期还剩 2 天,Python 爬取途牛网,揭秘哪里人少景美!
  9. SQL:postgresql查询某个字段最大值行的其他字段值
  10. layui 复选框checked获取值和赋值
  11. Dxg——Raspberry Pi Pico python 开发笔记整理分类合集【所有的相关记录,都整理在此】
  12. 与程序员朋友闲聊 通用权限管理系统有啥用?
  13. 带圈数字字体1-100
  14. DDcGAN:用于多分辨率图像融合的双判别器生成对抗网络
  15. IIS配置MIME类型
  16. 4.2.1 Duration and Convexity
  17. zabbix报警功能(邮件报警)---触发器/动作
  18. 计算机网络学习笔记(二)——网络边缘
  19. amd装linux不进pe,amdu盘启动,详细教您amd主板怎么设置u盘启动
  20. JVM是如何执行方法调用的?

热门文章

  1. html中间大两边小轮播代码,vue使用swiper实现中间大两边小的轮播图效果
  2. zblog php 安装,zblog教程:Z-BlogPHP如何安装
  3. pythonrequests库使用方法_python三方库之requests-快速上手
  4. element ui select 自动向上向下弹出_达观数据:Selenium使用技巧与机器人流程自动化实战...
  5. php开启慢查询,MySQL开启慢查询功能
  6. 数据库设计三大范式应用实例剖析(讲得比较清楚)
  7. 计算机英语讲课笔记01
  8. Java实训项目13:GUI学生信息管理系统 - 实现步骤 - 创建应用程序类
  9. ES6学习笔记03:变量的解构赋值
  10. 2.图像作为函数 | 裁剪、颜色通道、图像相加_5