结构型模式:享元模式
文章首发: 结构型模式:享元模式
七大结构型模式之六:享元模式。
简介
姓名 :享元模式
英文名 :Flyweight Pattern
价值观 :共享富贵
个人介绍 : Use sharing to support large numbers of fine-grained objects efficiently. 使用共享对象可有效地支持大量的细粒度的对象。 (来自《设计模式之禅》)
你要的故事
还记得笔袋么?可能有人已经忘记了,在写这篇文章之前其实我也忘了,从初中开始就再也没用过笔袋。拿笔袋来讲享元模式再适合不过了。笔袋放各种各样的笔,今天我们不讲别的,就讲蜡笔。前段时间在逛公园的时候,看到一位老师在画画,画的就是蜡笔画,第一次看到真正的蜡笔画,真的很震撼,原来蜡笔也可以把景色画得那么美。当时偷偷拍了一张,看下图。
我们就拿这幅画来说,里面画了草、树、路、山、天空等等。如果没有用享元模式,我们可能这样子实现。
蜡笔接口。
interface ICrayon { void draw(String place); }
蜡笔。
/** * 蜡笔 */ class Crayon implements ICrayon { private String color; public Crayon(String color) { System.out.println("---新建【" + color + "】蜡笔" ); this.color = color; } @Override public void draw(String place) { System.out.println("用" + this.color + "蜡笔画" + place); } }
测试代码。这幅画是小明和小红一起画,小明画了草和路,小红画了树和蓝天。
public class NoFlyweightTest { public static void main(String[] args) { drawByXiaoMing(); drawByXiaoHong(); } public static void drawByXiaoMing() { ICrayon greenCrayon = new Crayon("绿色"); greenCrayon.draw("草"); ICrayon grayCrayon = new Crayon("灰色"); grayCrayon.draw("路"); } public static void drawByXiaoHong() { ICrayon blueCrayon = new Crayon("蓝色"); blueCrayon.draw("蓝天"); ICrayon greenCrayon = new Crayon("绿色"); greenCrayon.draw("树"); } } 打印结果: ---新建【绿色】蜡笔 用绿色蜡笔画草 ---新建【灰色】蜡笔 用灰色蜡笔画路 ---新建【蓝色】蜡笔 用蓝色蜡笔画蓝天 ---新建【绿色】蜡笔 用绿色蜡笔画树
我们发现小明和小红都用了绿色蜡笔,而这里新建了 2 次绿色蜡笔,也就是在整个作画过程中,小明和小红并不是共用一套蜡笔,而是各自用一套蜡笔,在现实中是没什么问题的,但是在软件开发中,如果这种情况出现,其实相当于资源浪费,因为每个蜡笔都会占用内存,可以共用的我们尽量共用,节省一些内存空间,特别是出现很多这种可以共享却没有共享的对象时候。下面我们引入享元模式。享元模式实现方法相当于我们蜡笔都放在了笔袋,小明和小红用完就放到笔袋里面,每一种颜色的蜡笔只有一根,也就是他们共用一套蜡笔。代码如下所示。
笔袋代码。我们用了 Map 作为容器,如果容器里面没有想要颜色的蜡笔,则创建新的蜡笔,并存到容器里。
/** * 笔袋 */ class CrayonFactory { private static Map<String, ICrayon> data = new HashMap<>(); public static ICrayon getCrayon(String color) { if (data.containsKey(color)) { return data.get(color); } ICrayon crayon = new Crayon(color); data.put(color, crayon); return crayon; } }
测试代码。
public class FlyweightTest { public static void main(String[] args) { drawByXiaoMing(); drawByXiaoHong(); } public static void drawByXiaoMing() { ICrayon greenCrayon = CrayonFactory.getCrayon("绿色"); greenCrayon.draw("草"); ICrayon grayCrayon = CrayonFactory.getCrayon("灰色"); grayCrayon.draw("路"); } public static void drawByXiaoHong() { ICrayon blueCrayon = CrayonFactory.getCrayon("蓝色"); blueCrayon.draw("蓝天"); ICrayon greenCrayon = CrayonFactory.getCrayon("绿色"); greenCrayon.draw("树"); } } 打印结果: ---新建【绿色】蜡笔 用绿色蜡笔画草 ---新建【灰色】蜡笔 用灰色蜡笔画路 ---新建【蓝色】蜡笔 用蓝色蜡笔画蓝天 用绿色蜡笔画树
利用享元模式实现的结果,小红画树所用到的绿色蜡笔跟小明画草的绿色蜡笔一样,小红用到时并没有新建绿色蜡笔。
总结
是不是有一种,原来这就是享元模式的感觉?平时开发过程中经常见到这种因为很多重复的对象,所以利用享元模式来实现的场景。享元模式合理提高了对象的复用性,减少了程序的内存占用,还有一个提高性能的地方就是减少了对象创建的过程。好了,收下这个简单的设计模式。欢迎关注公众号,一起学习进步。
推荐阅读
公众号后台回复『大礼包』获取 Java、Python、IOS 等教程 加个人微信备注『教程』获取架构师、机器学习等教程

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
基于Spring Security Oauth2的SSO单点登录+JWT权限控制实践
概 述 在前文《基于Spring Security和 JWT的权限系统设计》之中已经讨论过基于 Spring Security和 JWT的权限系统用法和实践,本文则进一步实践一下基于 Spring Security Oauth2实现的多系统单点登录(SSO)和 JWT权限控制功能,毕竟这个需求也还是蛮普遍的。 代码已开源,放在文尾,需要自取 理论知识 在此之前需要学习和了解一些前置知识包括: Spring Security:基于 Spring实现的 Web系统的认证和权限模块 OAuth2:一个关于授权(authorization)的开放网络标准 单点登录 (SSO):在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统 JWT:在网络应用间传递信息的一种基于 JSON的开放标准((RFC 7519),用于作为JSON对象在不同系统之间进行安全地信息传输。主要使用场景一般是用来在 身份提供者和服务提供者间传递被认证的用户身份信息 要完成的目标 目标1:设计并实现一个第三方授权中心服务(Server),用于完成用户登录,认证和权限处理 目标2:可以在授权中心下挂载任意多个...
- 下一篇
cassandra百亿级数据库迁移实践
迁移背景 cassandra集群隔段时间出现rt飙高的问题,带来的影响就是请求cassandra短时间内出现大量超时,这个问题发生已经达到了平均两周一次的频率,已经影响到正常业务了。而出现这些问题的原因主要有以下3点: 当初设计表的时候partition key设计的不是很合理,当数据量上去(最大的单表行数达到百亿级)之后,出现了一些数据量比较大的partition。单partition最多的数据量达到了上百万行(cassandra不支持mysql的limit m, n的查询),当查询这个partition的数据时,会带来比较大的压力。 cassandra本身的墓碑机制,cassandra的一大特性就是快速写入,如果遇到delete一条记录时,cassandra并不会实时的对这条记录做物理删除,而是在这行记录上添加一个逻辑删除的标志位,而下次查询会load出这些已经删除了的记录,再做过滤。这样就可能带来及时某个partition的查询出的数据量不大,但是墓碑比较多的时候会带来严重的性能问题。 公司dba也不推荐使用cassandra,出现问题的时候,难于定位解决问题。所以决定将cass...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS8安装Docker,最新的服务器搭配容器使用
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题