• 设计模式 结构型模式 - 享元模式(七)


     一、概述

    定义:

    运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似对象的开销,从而提高系统资源的利用率。

    二、结构

    享元(Flyweight)模式中存在以下两种状态:

    (1)内部状态,即不会随着环境改变而改变的可共享部分。

    (2)外部状态,指随环境改变而改变的不可共享的部分。享元模式的实现要领就是区分应用中的两种状态,并将外部状态外部化。

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

    (1)抽象享元角色(Flyweight):通常是一个接口或抽象类,在抽象享元类中声明了具体享元类公共的方法,这些方法可以向外界提供享元对象的内部数据(内部状态),同时也可以通过这些方法来设置外部数据(外部状态)。

    (2)具体享元(Concrete Flyweight)角色:它实现了抽象享元类,称为享元对象;在具体享元类中为内部状态提供了存储空间。通常我们可以结合单例模式来设计具体享元类,为每一个具体享元类提供唯一的享元对象。

    (3)非享元(Unsharable Flyweight)角色:并不是所有的抽象享元类的子类都需要被共享,不能被共享的子类可以设计为非共享具体享元类;当需要一个非共享具体享元类的对象时可以总结通过实例化创建。

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

    三、案例实现

     1. 抽象享元角色

    1. /**
    2. * 抽象享元角色
    3. */
    4. public abstract class AbstractBox {
    5. //获取图形的方法
    6. public abstract String getShape();
    7. // 显示图形及颜色
    8. public void display(String color) {
    9. System.out.println("方块形状:" + this.getShape() + " 颜色:" + color);
    10. }
    11. }

    2. 具体享元角色

    1. /**
    2. * 具体享元角色【I】
    3. */
    4. public class IBox extends AbstractBox {
    5. @Override
    6. public String getShape() {
    7. return "I";
    8. }
    9. }

    3. 享元工厂角色

    1. /**
    2. * 享元工厂角色
    3. * 设计为单例
    4. */
    5. public class BoxFactory {
    6. private static HashMap map;
    7. private BoxFactory() {
    8. map = new HashMap();
    9. AbstractBox iBox = new IBox();
    10. AbstractBox lBox = new LBox();
    11. AbstractBox oBox = new OBox();
    12. map.put("I", iBox);
    13. map.put("L", lBox);
    14. map.put("O", oBox);
    15. }
    16. public static final BoxFactory getInstance() {
    17. return SingletonHolder.INSTANCE;
    18. }
    19. private static class SingletonHolder {
    20. private static final BoxFactory INSTANCE = new BoxFactory();
    21. }
    22. public AbstractBox getBox(String key) {
    23. return map.get(key);
    24. }
    25. }

    4. 客户端类

    1. public class Client {
    2. public static void main(String[] args) {
    3. BoxFactory factory = BoxFactory.getInstance();
    4. AbstractBox box1 = factory.getBox("I");
    5. box1.display("灰色");
    6. AbstractBox box2 = factory.getBox("L");
    7. box1.display("红色");
    8. AbstractBox box3 = factory.getBox("O");
    9. box1.display("蓝色");
    10. AbstractBox box4 = factory.getBox("O");
    11. box1.display("黑色");
    12. System.out.println("两次获取的O对象是否是同一个对象:" + (box3 == box4));
    13. }
    14. }

    四、优缺点和使用场量

    优点:

    (1)极大减少内存中相似或相同对象数量,节约系统资源,提供系统性能

    (2)享元模式中的外部状态相对独立,且不影响内部状态

    缺点:

    (1)为了使对象可以共享,需要将享元对象的部分状态外部化,分离内部状态和外部状态,使程序逻辑

    使用场景:

    (1)一个系统有大量相同或者相似的对象,造成内存的大量耗费

    (2)对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。

    (3)在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源,因此,应当在需要多次重复使用享元对象时才值得使用享元模式

    五、JDK 源码解析

     

     

  • 相关阅读:
    L1-008 求整数段和分数 10
    Java拼图
    快速创建软件安装包-ClickOnce
    企业云盘软件世界排行榜:提升企业文件管理效率的最佳工具
    树莓派(Raspberry Pi)miniDLNA服务搭建
    如何减少电气设备漏电问题,其解决方案有哪些?
    链路状态路由协议OSPF的LSA头部讲解
    全球数字高程数据(DEM)详解,还有地形晕渲、等高线等干货
    FPV眼镜和VR眼镜的区别,穿越机搭配FPV眼镜优缺点分析
    .NET6: 开发基于WPF的摩登三维工业软件 (8) - MVVM
  • 原文地址:https://blog.csdn.net/yirenyuan/article/details/127665338