详解设计模式:享元模式
创始人
2024-03-07 14:56:37
0

享元模式(Flyweight Pattern),是对象池的一种体现,也是 GoF 的 23 种设计模式中的一种结构型设计模式。

享元模式 主要用于减少创建对象的数量,以减少内存占用和提高性能。它提供了减少对象数量从而改善应用所需的对象结构的方式。

享元模式 尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

~

本篇内容包括:关于享元模式、享元模式 Demo


文章目录

    • 一、关于享元模式
        • 1、关于享元模式
        • 2、关于享元模式的构成
        • 3、关于享元模式的XML
        • 4、关于享元模式的应用场景
        • 5、关于享元模式在 Java 中的应用
        • 6、关于享元模式的优缺点
    • 二、享元模式 Demo
        • 1、Demo 设计
        • 2、Demo 实现


一、关于享元模式

1、关于享元模式

享元模式(Flyweight Pattern),是对象池的一种体现,也是 GoF 的 23 种设计模式中的一种结构型设计模式。

享元模式 主要用于减少创建对象的数量,以减少内存占用和提高性能。它提供了减少对象数量从而改善应用所需的对象结构的方式。

享元模式 尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

2、关于享元模式的构成

享元模式主要包含四种角色:

  1. 抽象享元(Flyweight)角色:是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
  2. 具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。
  3. 非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
  4. 享元工厂(Flyweight Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。

3、关于享元模式的XML

享元模式

4、关于享元模式的应用场景

当系统中多处需要同一组信息时,可以吧这些信息封装到一个对象中,然后对该对象进行缓存,这样,一个对象就可以提供给多处需要使用的地方,避免大量同一对象多次创建,消耗大量内存空间。
享元模式其实就是工厂模式的一个改进机制,享元模式同样要求创建一个或一组对象,并且就是通过工厂方法生成对象的,只不过享元模式中为工厂方法增加了缓存这一功能。主要总结为以下应用场景:

  1. 常常应用于系统底层的开发,以便解决系统的性能问题。
  2. 系统有大量相似的对象、需要缓存池的场景。

在生活中的享元模式也很常见,比如中介机构的房源共享,再比如全国社保联网。

5、关于享元模式在 Java 中的应用

在 Java 中最直观的享元模式就是在 Boolean,Byte,Integer,Long,Character 这些包装类中,他们都提供了valueOf()方法。

比如:Long 的 valueOf() 方法会缓存数值 -127~128 之间的 Long 对象,在这个范围之间就会直接在这个里面去取,大于这个范围才会去 new Long 对象

public static Long valueOf(long l) {final int offset = 128;if (l >= -128 && l <= 127) { // will cachereturn LongCache.cache[(int)l + offset];}return new Long(l);}private static class LongCache {private LongCache(){}static final Long cache[] = new Long[-(-128) + 127 + 1];static {for(int i = 0; i < cache.length; i++)cache[i] = new Long(i - 128);}}

Byte,Short,Long 的范围是 -127~128 之间。

Character 是 0~127 之间。

Integer 是 -127~128 之间,最小值不能改变,但是最大值可以通过虚拟机参数进行改变。-Djava.long.Intger.IntegerCache.high 来改变

Boolean 缓存了 TRUE 和 FALSE

6、关于享元模式的优缺点

# 享元模式的优点:

  1. 减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率;
  2. 减少内存之外的其它资源占用。

# 享元模式的缺点:

  1. 关注内、外部状态、关注线程安全问题;
  2. 使系统、程序复杂化。

二、享元模式 Demo

1、Demo 设计

俄罗斯方块有不同的形状,我们可以对这些形状向上抽取出 AbstractBox,用来定义共性的属性和行为。

接下来就是定义不同的形状了,IBox类、LBox类、TBox类等。

提供了一个工厂类(BoxFactory),用来管理享元对象(也就是 AbstractBox 子类对象),该工厂类对象只需要一个,所以可以使用单例模式。并给工厂类提供一个获取形状的方法。

2、Demo 实现

# AbstractBox 抽象享元角色

public abstract class AbstractBox {public abstract String getShape();public void display(String color) {System.out.println("方块形状:" + this.getShape() + " 颜色:" + color);}
}

# IBox/LBox/TBox 具体享元角色

public class IBox extends AbstractBox {@Overridepublic String getShape() {return "I";}
}public class LBox extends AbstractBox {@Overridepublic String getShape() {return "L";}
}public class TBox extends AbstractBox {@Overridepublic String getShape() {return "T";}
}

# BoxFactory 享元工厂

public class BoxFactory {private static HashMap map;private BoxFactory() {map = new HashMap();AbstractBox iBox = new IBox();AbstractBox lBox = new LBox();AbstractBox oBox = new OBox();map.put("I", iBox);map.put("L", lBox);map.put("O", oBox);}public static final BoxFactory getInstance() {return SingletonHolder.INSTANCE;}private static class SingletonHolder {private static final BoxFactory INSTANCE = new BoxFactory();}public AbstractBox getBox(String key) {return map.get(key);}
}

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...