前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式---享元模式

设计模式---享元模式

作者头像
技术文章精选
发布2022-11-08 16:38:44
2280
发布2022-11-08 16:38:44
举报
文章被收录于专栏:优质文章优质文章

简述

  • 类型:结构型
  • 目的:降低对象创建时大量属性也随之被新建而带来的性能上的消耗

话不多说,我们看一个案例。

优化案例

最初版v0

现在需要采购一批办公用的电脑,以下是Computer类的定义。

代码语言:javascript
复制
public class Computer {   	private String sn; // 序列号,电脑的唯一识别码    private String brand; // 品牌    private String title; // 一个系列的名称,如Lenovo的Thinkpad    private String cpu;    private String memory;    private String disk;    private String gpu;    private String keyboard;    private String display;        public Computer(String sn, String brand,                     String title, String cpu,                     String memory, String disk,                     String gpu, String keyboard,                     String display) {        this.sn = sn;        this.brand = brand;        this.title = title;        this.cpu = cpu;        this.memory = memory;        this.disk = disk;        this.gpu = gpu;        this.keyboard = keyboard;        this.display = display;    }}

现在公司要采购两种电脑总计1000台,以下是模拟采购的代码。

代码语言:javascript
复制
public class Client {    public static void main(String[] args) {        List<Computer> purchase = new ArrayList<>();        for (int i = 0; i < n; i ++) {            purchase.add(new Computer(UUID.randomUUID().toString(),                         "华为", "MateBook16", "锐龙7 5800H标压",                         "16GB DDR4 双通道", "512GB NVMe PCle SSD",                          "gpu", "全尺寸背光键盘", "16英寸");        }    }}

循环中每一次都要生成一个新的Computer对象,并且该对象中有很多String类型的属性,因为String是一个引用数据类型,所以会随之生成很多的引用,从而降低系统的性能。实际上,采购的计算机只要型号相同,配置参数也就随之相同且不会再改变,唯一会改变的其实就只有机器的序列号而已,所以我们没有每追加一台电脑就重新设置一遍所有参数的必要。而且如果中途需要对于采购订单的机器参数进行修改,那就必须迭代清单中的所有对象,对每个对象进行修改,又是一件效率低下的事。

为了解决这个问题,我们引入了享元模式。下面是修改后的代码。

修改版v1

代码语言:javascript
复制
public class Computer {   	private String sn; // 序列号,电脑的唯一识别码    private ComputerSpec spec; // 依赖规格的具体属性 → 依赖ComputerSpec类,迪米特法则        public Computer(String sn, ComputerSpec spec) {        this.sn = sn;        this.spec = spec;        this.title = title;        this.model = model;        this.cpu = cpu;        this.memory = memory;        this.disk = disk;        this.gpu = gpu;        this.keyboard = keyboard;        this.display = display;    }} public enum ComputerSpec { // 定义一个计算机规格类    MATEBOOK16("华为", "MateBook16", "锐龙7 5800H标压",               "16GB DDR4 双通道", "512GB NVMe PCle SSD",                "gpu", "全尺寸背光键盘", "16英寸");        public String brand; // 品牌    public String title; // 一个系列的名称,如Lenovo的Thinkpad    public String cpu;    public String memory;    public String disk;    public String gpu;    public String keyboard;    public String display;        ComputerSpec(String sn, String brand,                  String title, String cpu,                  String memory, String disk,                  String gpu, String keyboard,                  String display) {        this.brand = brand;        this.title = title;        this.model = model;        this.cpu = cpu;        this.memory = memory;        this.disk = disk;        this.gpu = gpu;        this.keyboard = keyboard;        this.display = display;    }}

来看看修改后的采购如何模拟实现。

代码语言:javascript
复制
public class Client {    public static void main(String[] args) {        List<Computer> purchase = new ArrayList<>();        for (int i = 0; i < n; i ++) {            purchase.add(new Computer(UUID.randomUUID().toString(),                                       ComputerSpec.MATEBOOK16));        }        // 由于订单错误,现在需要批量将MateBook16修改为MateBook16s        ComputerSpec.MATEBOOK16.title = "MateBook16s";    }}

使用享元模式,将Computer对象创建时不变的属性封装到ComputerSpec中,内部状态外部状态分开,内部状态直接引用相同的数据源,而不是每次都重新生成新的数据,从而大幅提升系统性能。并且,需要对于数据统一修改时,由于数据源引用相同,只需要修改内部状态的对应属性即可修改所有数据。

  • 内部状态:不可变对象。被共享的数据。如,案例中的ComputerSpec
  • 外部状态:随着业务而改变数据。不被共享的数据。如,案例中的sn

总结

优点

  1. 由于多个对象的属性引用相同,从而极大程度的降低了系统性能的消耗。
  2. 由于多个属性被封装成新的类,对象与属性间的依赖减少,从而降低了对象创建的复杂度。

缺点

  1. 增加了开发人员对于系统业务理解的难度。

适用场景

  1. 当对象的绝大多数属性与对象本身不是一对一而是一对多的关系时。换言之,多个对象公用一套属性时

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
目录
  • 简述
  • 优化案例
    • 最初版v0
      • 修改版v1
      • 总结
        • 优点
          • 缺点
            • 适用场景
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档