当前位置: 首页 > article >正文

设计模式--享元模式【结构型模式】

设计模式的分类

我们都知道有 23 种设计模式,这 23 种设计模式可分为如下三类:

  • 创建型模式(5 种):单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。
  • 结构型模式(7 种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  • 行为型模式(11 种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

在这里插入图片描述

设计模式系列文章传送门

设计模式的 7 大原则

设计模式–单例模式【创建型模式】

设计模式–工厂方法模式【创建型模式】

设计模式–抽象工厂模式【创建型模式】

设计模式–建造者模式【创建型模式】

设计模式–原型模式【创建型模式】

设计模式–适配器模式【结构型模式】

设计模式–装饰器模式【结构型模式】

设计模式–代理模式【结构型模式】

设计模式–外观模式(门面模式)【结构型模式】

设计模式–桥接模式【结构型模式】

设计模式–组合模式【结构型模式】

什么是享元模式

享元模式使用优化系统性能的设计模式,享元模式的核心在于一个“享”字,也就是共享的意思,享元模式主要通过共享对象来减少系统中对象的数量,享元模式将对象分为内部状态和外部状态,内部状态的对象不会变化,外部对象会发生变化,享元模式本质就是缓存内部状态的共享对象,降低内存消耗。

享元模式的组成部分

  • 抽象享元部分:享元对象抽象类或者接口,并定义出享元对象的外部状态和内部状态的的方法。
  • 具体享元部分:实现抽象享元类或者接口,并实现了中的方法,简单来说具体享元部分就是可以被共享的对象。
  • 享元工厂:负责创建和管理享元对象,维护了一个享元对象的缓存池,客户端请求获取享元对象时候,享元工厂会先检查缓存池中是否有相同的内部状态的享元对象,如果存在就直接返回,否则创建一个新的享元对象返回,同时也会把这个新创建的享元对象加入到缓存池,一般会使用一个 Map 存储已经创建的享元对象。

享元模式案例演示

我们再次以家用小汽车做为享元模式的演示对象,汽车就是一个享元对象,我们知道同样一款汽车会有不同颜色、不同续航里程,客户端在获取小汽车对象的时候,完全相同属性的小汽车对象就可以看做是一个内部状态的享元对象,可以共享使用。

XiaoMiCar(抽象享元部分)

我们定义 XiaoMiCar 为抽象享元部分,代码如下:

public class XiaoMiCar {

    //颜色
    public String color;

    //续航
    public String batteryLife;

    public XiaoMiCar(String color, String batteryLife) {
        this.color = color;
        this.batteryLife = batteryLife;
    }


    public void xiaoMiCar() {
        System.out.println("当前款小米汽车颜色:" + color + ",续航:" + batteryLife);
    }

}

XiaoMiSu7Car(具体享元部分)

我们定义 XiaoMiSu7Car 为具体享元部分,代码如下:

public class XiaoMiSu7Car extends XiaoMiCar {

    public XiaoMiSu7Car(String color, String batteryLife) {
        super(color, batteryLife);
    }

    @Override
    public void xiaoMiCar() {
        System.out.println("当前款小米su7汽车颜色:" + color + ",续航:" + batteryLife);
    }
    
}

XiaoMiYu7Car(具体享元部分)

我们定义 XiaoMiYu7Car 为具体享元部分,代码如下:

public class XiaoMiYu7Car extends XiaoMiCar {

    public XiaoMiYu7Car(String color, String batteryLife) {
        super(color, batteryLife);
    }

    @Override
    public void xiaoMiCar() {
        System.out.println("当前款小米yu7汽车颜色:" + color + ",续航:" + batteryLife);
    }

}

XiaoMiCarFactory(享元工厂)

我们定义 XiaoMiCarFactory 为享元工厂,内部有一个 Map 来做为缓存容器,并提供了一个方法来获取享元对象,代码如下:

public class XiaoMiCarFactory {

    //享元工厂
    public static Map<String, XiaoMiCar> carMap = new HashMap<>();

    //维护享元对象
    public static XiaoMiCar queryCar(String color, String batteryLife, String type) {
        String carKey = color + "-" + batteryLife;
        XiaoMiCar xiaoMiCar = carMap.get(carKey);
        if (xiaoMiCar == null) {
            System.out.println(carKey+"为空,需要生产该类型的车");
            if ("yu7".equals(type)) {
                xiaoMiCar = new XiaoMiYu7Car("海湾蓝", "700KM");
            } else {
                xiaoMiCar = new XiaoMiSu7Car("钻石黑", "500KM");
            }
            //加入缓存
            carMap.put(carKey, xiaoMiCar);
            return xiaoMiCar;
        } else {
            System.out.println(carKey+"车已经存在,可以直接使用");
            return xiaoMiCar;
        }

    }

}

XiaoMiCarClient(客户端)

我们定义 XiaoMiCarClient 客户端,多次获取同一款车型,来看看享元模式的效果,代码如下:

public class XiaoMiCarClient {

    public static void main(String[] args) {
        //第一次获取 xiaoMiSu7Car
        XiaoMiCar xiaoMiSu7Car = XiaoMiCarFactory.queryCar("钻石黑", "500KM", "su7");
        xiaoMiSu7Car.xiaoMiCar();
        //第一次获取 xiaoMiYu7Car
        XiaoMiCar xiaoMiYu7Car = XiaoMiCarFactory.queryCar("海湾蓝", "700KM", "yu7");
        xiaoMiYu7Car.xiaoMiCar();
        //第二次获取 xiaoMiSu7Car
        XiaoMiCar xiaoMiSu7Car2 = XiaoMiCarFactory.queryCar("钻石黑", "500KM", "su7");
        xiaoMiSu7Car2.xiaoMiCar();
        //第二次获取 xiaoMiYu7Car
        XiaoMiCar xiaoMiYu7Car2 = XiaoMiCarFactory.queryCar("海湾蓝", "700KM", "yu7");
        xiaoMiYu7Car2.xiaoMiCar();
    }

}

执行结果如下:

钻石黑-500KM为空,需要生产该类型的车
当前款小米su7汽车颜色:钻石黑,续航:500KM
海湾蓝-700KM为空,需要生产该类型的车
当前款小米yu7汽车颜色:海湾蓝,续航:700KM
钻石黑-500KM车已经存在,可以直接使用
当前款小米su7汽车颜色:钻石黑,续航:500KM
海湾蓝-700KM车已经存在,可以直接使用
当前款小米yu7汽车颜色:海湾蓝,续航:700KM

从结果可以看出同一款小汽车第一次获取的时候都没有获取到,重新创建了对象,第二次获取的时候就直接从享元工厂的缓存中获取到了对象,结果符合预期。

享元模式的优缺点

优点:

  • 对象共享之后,避免重复对象的重复创建,提高了内存使用率。
  • 对象共享之后,避免了重复对象的创建过程,减少了开销,提高了程序的响应性能。
  • 内部对象和外部对象的隔离降低了对象的耦合度,内部对象由享元模式维护,外部对象由客户端维护。

缺点:

  • 增加了系统的复杂性,因为要区分内部对象和外部对象。
  • 对研发人员有一定的技术要求,需要清晰的分清内部对象和外部对象。

享元模式的使用场景

  • 业务场景中有大量的相似对象的时候,可以使用享元模式减少内存开销。
  • 对象的创建开销较大的时候,可以使用享元模式来降低对象创建的开销。

总结:本篇简单分享享元模式的概念和使用方式,享元模式重点在一个“享”字,主要目的是共享内部对象,减少对象的创建与销毁,我们在业务研发的时候也会常常用到,希望可以帮助到不太熟悉享元模式的朋友。

如有不正确的地方欢迎各位指出纠正。


http://www.kler.cn/a/471290.html

相关文章:

  • doris:远程存储
  • 三极管工作状态分析
  • 设计模式——泛型单例类
  • 【JMM】Java 内存模型
  • 源代码编译安装X11及相关库、vim,配置vim(3)
  • 【C语言程序设计——选择结构程序设计】求阶跃函数的值(头歌实践教学平台习题)【合集】
  • 【python】字符串元素的访问与截取
  • QT c++ 自定义按钮类 加载图片 美化按钮
  • LeetCode 3019.按键变更的次数:遍历(转小写)
  • selenium找不到元素解决方案-切换iframe
  • Bash语言的文件操作
  • HTML5-标签
  • Swin-Transformer
  • Web渗透测试之XSS跨站脚本攻击分类 详解
  • Effective C++读书笔记——item11(自赋值)
  • Python中判断语句及循环语句练习
  • 对于安装完服务后,无法执行命令的问题处理
  • 行为树详解(6)——黑板模式
  • halcon三维点云数据处理(五)创建代表工具和机器人底座的3D模型
  • Qt仿音乐播放器:客户端唯一化
  • 使用 httputils + chronicle-bytes 实现金融级 java rpc
  • 【免费】2004-2019年各省规模以上工业企业RD经费面板数据
  • RabbitMQ-死信队列
  • android系统的一键编译与非一键编译 拆包 刷机方法
  • 【数据可视化】数据可视化看板需求梳理模板(含示例)
  • Linux 系统清理命令大全