1. 应用场景

当我们项目中创建很多对象,而且这些对象存在许多相同模块,这时,我们可以将这些相同的模块提取出来采用享元模式生成单一对象,再使用这个对象与之前的诸多对象进行配合使用,这样无疑会节省很多空间。

2. 概念

说到享元模式,第一个想到的应该就是池技术了,String常量池、数据库连接池、缓冲池等等都是享元模式的应用,所以说享元模式是池技术的重要实现方式。

比如我们每次创建字符串对象时,都需要创建一个新的字符串对象的话,内存开销会很大,所以如果第一次创建了字符串对象“adam“,下次再创建相同的字符串”adam“时,只是把它的引用指向”adam“,这样就实现了”adam“字符串再内存中的共享。

举个最简单的例子,网络联机下棋的时候,一台服务器连接了多个客户端(玩家),如果我们每个棋子都要创建对象,那一盘棋可能就有上百个对象产生,玩家多点的话,因为内存空间有限,一台服务器就难以支持了,所以这里要使用享元模式,将棋子对象减少到几个实例。下面给出享元模式的定义。

3. Class Diagram

  • Flyweight:享元对象
  • IntrinsicState:内部状态,享元对象共享内部状态
  • ExtrinsicState:外部状态,每个享元对象的外部状态不同

Flyweight是抽象享元角色。它是产品的抽象类,同时定义出对象的外部状态和内部状态(外部状态及内部状态相关内容见后方)的接口或实现;ConcreteFlyweight是具体享元角色,是具体的产品类,实现抽象角色定义的业务;lyweightFactory是享元工厂,它用于构造一个池容器,同时提供从池中获得对象的方法。

4. Implementation

public abstract class Flyweight {//内部状态public String intrinsic;//外部状态protected final String extrinsic;//要求享元角色必须接受外部状态public Flyweight(String extrinsic) {this.extrinsic = extrinsic;}//定义业务操作public abstract void operate(int extrinsic);public String getIntrinsic() {return intrinsic;}public void setIntrinsic(String intrinsic) {this.intrinsic = intrinsic;}}public class ConcreteFlyweight extends Flyweight {//接受外部状态public ConcreteFlyweight(String extrinsic) {super(extrinsic);}//根据外部状态进行逻辑处理@Overridepublic void operate(int extrinsic) {System.out.println("具体Flyweight:" + extrinsic);}}public class FlyweightFactory {//定义一个池容器private static HashMap<String, Flyweight> pool = new HashMap<>();//享元工厂public static Flyweight getFlyweight(String extrinsic) {Flyweight flyweight = null;if(pool.containsKey(extrinsic)) {    //池中有该对象flyweight = pool.get(extrinsic);System.out.print("已有 " + extrinsic + " 直接从池中取---->");} else {//根据外部状态创建享元对象flyweight = new ConcreteFlyweight(extrinsic);//放入池中pool.put(extrinsic, flyweight);System.out.print("创建 " + extrinsic + " 并从池中取出---->");}return flyweight;}
}public class UnsharedConcreteFlyweight extends Flyweight {public UnsharedConcreteFlyweight(String extrinsic) {super(extrinsic);}@Overridepublic void operate(int extrinsic) {System.out.println("不共享的具体Flyweight:" + extrinsic);}}public class Client {public static void main(String[] args) {int extrinsic = 22;Flyweight flyweightX = FlyweightFactory.getFlyweight("X");flyweightX.operate(++ extrinsic);Flyweight flyweightY = FlyweightFactory.getFlyweight("Y");flyweightY.operate(++ extrinsic);Flyweight flyweightZ = FlyweightFactory.getFlyweight("Z");flyweightZ.operate(++ extrinsic);Flyweight flyweightReX = FlyweightFactory.getFlyweight("X");flyweightReX.operate(++ extrinsic);Flyweight unsharedFlyweight = new UnsharedConcreteFlyweight("X");unsharedFlyweight.operate(++ extrinsic);}}运行结果:
创建 X 并从池中取出---->具体Flyweight:23
创建 Y 并从池中取出---->具体Flyweight:24
创建 Z 并从池中取出---->具体Flyweight:25
已有 X 直接从池中取---->具体Flyweight:26
不共享的具体Flyweight:27

5. 优点和缺点

5.1 优点

  • 减少运行时对象实列的个数,节省内存。
  • 将许多“虚拟”对象的状态集中管理。

5.2 用途和缺点

  • 当一个类有许多实列,而这些实列能被同一个方法控制的时候,我们就可以使用享元设计模式。
  • 享元设计模式缺点在于,一旦你实现了它,那么单个逻辑实列将无法永远独立而不同的行为。

6. JDK

Java 利用缓存来加速大量小对象的访问时间。

  • java.lang.Integer#valueOf(int)
  • java.lang.Boolean#valueOf(boolean)
  • java.lang.Byte#valueOf(byte)
  • java.lang.Character#valueOf(char)

Java设计模式(十八):享元设计模式相关推荐

  1. GoF设计模式(十二) - 享元模式

    前言 享元模式(Flyweight Pattern)运用共享技术有效地支持大量细粒度的对象,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的 ...

  2. 设计模式(十)享元模式Flyweight(结构型)

    设计模式(十)享元模式Flyweight(结构型) 说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释 ...

  3. 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...

  4. 黑马程序员--高新技术--静态导入,基本数据类型拆箱与装箱,享元设计模式

    静态导入 import语句可以导入一个类或某个包中的所有类 import static语句导入一个类中的某个静态方法或所有静态方法或静态变量 使用静态导入可以使被导入类的静态变量和静态方法在当前类直接 ...

  5. Integer注意_享元设计模式

    public class IntegerNote{ public static void main(String[] args){   Integer d1=100;   Integer d2=100 ...

  6. 结构设计模式 - Flyweight设计模式(享元设计模式)

    结构设计模式 - Flyweight设计模式 今天我们将研究Flyweight 设计模式,Flyweight设计模式又被称为 享元设计模式 . 目录[ 隐藏 ] 1 Flyweight设计模式 1.1 ...

  7. 设计模式学习笔记——享元(Flyweight)模式

    设计模式学习笔记--享元(Flyweight)模式 @(设计模式)[设计模式, 享元模式, flyweight] 设计模式学习笔记享元Flyweight模式 基本介绍 享元案例 类图 实现代码 Big ...

  8. 结构型设计模式(五) 之 享元模式是池技术的表现

    1 定义 享元模式(Flyweight Pattern)属于结构型设计模式之一,它主要是使用共享对象有效地避免了创建过多的性质相近的对象,从而降低内存的占用,提高程序的性能.它也是池技术的重要实现方式 ...

  9. 小白学JAVA之十八——泛型

    小白学JAVA之十八--泛型 一. 基本概念 通常情况下集合中可以存放不同类型的对象,是因为将所有对象都看做Object类型放入的,因此从集合中取出元素时也是Object类型,为了表达该元素真实的数据 ...

最新文章

  1. 51Nod:1085 背包问题
  2. Linux 服务器安全技巧
  3. ubuntu 搭建webrtc环境
  4. win10网络不出现计算机列表,win10网络发现已关闭网络计算机和设备不可见怎么办?...
  5. 项目经理案头手册学习系列【12】——使用挣值分析法控制项目
  6. 《利用Python》进行数据分析:Numpy基础2 创建数组
  7. 计算机网络是由一组结点组成吗,分布式数据库系统是由一组数据组成的,这组数据分布在计算机网络的不同计算机上,网络中的每个结点_考题宝...
  8. Tomcat启动报404(eclipse)
  9. 消息摘要的编程使用(MD5、SHA、HMAC)
  10. Linux学习笔记-消息队列的接收
  11. 最新小白详细描述在centos7.5上安装python3并使用Nginx+virtualenv+supervisor来部署tornado项目(整理集合结合实际)系列2
  12. linkedin 爬虫
  13. hutool工具私人学习笔记
  14. 交通部 808 协议2019版 - 免费下载 - 官网下载
  15. 吉林大学计算机学院三等奖学金,吉林大学奖学金评定方案.doc
  16. php yaf twig,GitHub - cheerego/happy_yaf: 搭建一个可用的Yaf,包括Laravel的Eloquent ORM、Twig、脚手架、Whoops和使用用例...
  17. Apk脱壳圣战之---脱掉 爱加密 的壳
  18. java 获取 yyyymmdd_从JS日期对象获取YYYYMMDD格式的字符串?
  19. 一个网课开发者复工后的一个月
  20. 网页设计Hero Image

热门文章

  1. Node.js:Web模块、文件系统
  2. Java数据库连接方法
  3. P1133 教主的花园
  4. Linux系统下GCC编译错误:“undefined reference to ‘sqrt‘”
  5. 【计算机视觉】几个计算机视觉库
  6. 计算机视觉领域最全汇总(第1部分)
  7. 为什么要学C语言及C语言存在的意义,新手经常犹豫学不学C语言
  8. kubernetes(k8s)之yaml文件详解
  9. 10进制转换成16进制
  10. linux转mysql_转linux下mysql命令