23. 享元模式

作者: Next_吴思成 | 来源:发表于2018-07-09 23:21 被阅读0次

定义

享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。

通俗理解

大家都去过图书馆,图书馆里面有书、桌子、电脑,这些东西都是公用的,只需要你注册一个读书证,就能够使用到这些公共资源。那如果这些资源并不是公用的,将会发生什么事情?首先,图书馆要统计某天进入图书馆的人数、他们对桌子、对电脑、对书籍的要求;然后,图书馆要拿着统计的清单,到市场进行采购,运回图书馆提供读者使用;最后,当读者使用过后,把这堆桌子和电脑销毁,烧掉或者回收。

这真是一个土豪的世界。

在编程的时候,也需要考虑到,我们系统的资源并不是无限增长的,总会有一个上限,到达上限之后还继续申请资源,只会发生溢出,整个系统都会挂掉。那么,在new一个对象的时候,是否想到这个对象也占内存?是否知道如果大量的对象堆积的时候,也会造成系统的崩溃?就像图书馆的公用资源一样,如果对每一个读者都定制服务,都购买一张桌子、买一台电脑,那么再多的资本都会白白消耗掉。

对于图书馆来讲,最佳的方式,就是买一批桌子,这一批桌子是大家公用的,这样才能解决公用资源无限增长的问题。对于程序而言,我们创建对象的时候,应该也有这样的实现,如果对象是类似的,那么我们就从公共资源(对象池)里面取,这样才能大大降低系统的资源开销。

示例

业务按照图书馆的桌子来定义。

渣渣程序

每一个用户都new一个对象。
桌子类

public class Desk {
    private String str;
    public Desk(String str) {
        this.str = str;
    }
    public void info() {
        System.out.println("这是一张桌子"+str);
    }
}

主入口

public class Main {
    public static void main(String[] args) {
        Desk desk1 = new Desk("desk1");
        Desk desk2 = new Desk("desk2");
        // ...
        desk1.info();
        desk2.info();
        //...
    }
}

优化

类图

程序

桌子通用抽象类和实现类

public abstract class BaseDesk {
    public abstract String getInfo();
    public void info() {
        System.out.println("桌子信息为:" + this.getInfo());
    }
}
public class Desk1 extends BaseDesk {
    @Override
    public String getInfo() {
        return "桌子1";
    }
}
public class Desk2 extends BaseDesk {
    @Override
    public String getInfo() {
        return "桌子2";
    }
}

桌子工厂

public class DeskFactory {
    private static DeskFactory factory = new DeskFactory();
    private static Map<String, BaseDesk> publicDesk;

    public DeskFactory() {
        publicDesk = new HashMap<>(2);
        BaseDesk desk1 = new Desk1();
        BaseDesk desk2 = new Desk2();
        publicDesk.put("desk1", desk1);
        publicDesk.put("desk2", desk2);
    }

    public static DeskFactory getFactory() {
        return factory;
    }

    public static BaseDesk getDesk(String desk) {
        return publicDesk.get(desk);
    }
}

调用主类

public class Main {
    public static void main(String[] args) {
        DeskFactory factory = DeskFactory.getFactory();
        BaseDesk desk1_1 = factory.getDesk("desk1");
        BaseDesk desk1_2 = factory.getDesk("desk1");
        System.out.println(desk1_1==desk1_2);//true
        desk1_1.info();//桌子信息为:桌子1
        desk1_2.info();//桌子信息为:桌子1
    }
}

从上面的程序可以知道,最重要的是就是对象池,所有的数据都是从对象池里面获取的。

存在一种情况,桌子都是定制的,张张都一样,如果我需要特殊的桌子,那么要怎么处理呢?其实这就涉及了对象的内部状态和外部状态了,内部状态是指内部的不随着环境改变而改变的状态,例如程序里面的桌子1就是桌子1,不可能变成桌子2;而外部状态是随着环境改变而改变的,例如有个人带了瓶颜料去图书馆,他可以把他那张桌子喷成白色的,程序上只需要在在BaseDesk相关的代码就可以了。

颜色

public class Color {
    private String color;
    public Color(String color) {
        this.color = color;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
}

基础桌子类

public abstract class BaseDesk {
    //...
    public void info(Color color) {
        System.out.println("桌子信息为:" + this.getInfo()+",颜色为:"+color.getColor());
    }
    //...
}

入口

desk1_1.info(new Color("白色"));
desk1_1.info(new Color("黑色"));

优点

  1. 减少内存中对象的数量,相似相同的对象中内存只有一份,节约系统资源;
  2. 内外部状态分开,相互不影响。

缺点

  1. 区分内外部状态,使系统的逻辑复杂;
  2. 外部状态使得系统的运行时间变长。

应用场景

  1. 大量的相同或者相似的对象,造成内存的大量消耗;
  2. 大部分状态都可以外部化的,不适合内部状态容易变动的;
  3. 池化的技术消耗资源,多次重复使用的享元对象才值得使用享元模式。

实例

JDK String,使用常量池存储

吐槽

就是池化技术,从Map里面获取对象。

代码

e23_flyweight_pattern

https://www.jianshu.com/p/e6384fd3ad1d

相关文章

  • 23. 享元模式

    定义 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的...

  • 设计模式之享元模式(flyweight模式)

    引入享元模式 享元模式的实例 享元模式的分析 引入享元模式 flyweight是轻量级的意思,指的是拳击比赛中选手...

  • 第4章 结构型模式-享元模式

    一、享元模式的简介 二、享元模式的优缺点 三、享元模式的实例

  • 享元模式

    一、享元模式介绍 二、享元模式代码实例

  • 设计模式--享元模式

    目录 本文的结构如下: 引言 什么是享元模式 模式的结构 典型代码 代码示例 单纯享元模式和复合享元模式 模式扩展...

  • 享元模式C++

    享元模式,就是运用共享技术有效地支持大量细粒度的对象。 享元模式结构图 享元模式基本代码 应用场景 享元模式可以避...

  • 设计模式之——享元模式

    1 享元模式的定义 享元模式:使用共享对象可有效地支持大量细粒度的对象。享元模式是池技术的重要实现方式。享元模式的...

  • 好程序员Java培训​分享java设计模式之享元模式

    好程序员Java培训​分享java设计模式之享元模式,Java设计模式中的享元模式。享元模式有点类似于单例...

  • 结构型模式:享元模式

    文章首发:结构型模式:享元模式 七大结构型模式之六:享元模式。 简介 姓名 :享元模式 英文名 :Flyweigh...

  • Java设计模式(三)

    talk is cheap show me the code 享元模式 享元模式 责任链模式 责任链模式Filte...

网友评论

    本文标题:23. 享元模式

    本文链接:https://www.haomeiwen.com/subject/nbqoyftx.html