设计模式(结构型设计模式——享元模式)

设计模式(结构型设计模式——享元模式)

享元模式

基本定义

  • 享元模式就是运行共享技术有效地支持大量细粒度(对象相似度较高的属性)对对象的复用,系统使用少量的对象,而且这些都比较相似,状态变化小,可以实现对象的多次复用。
  • 享元模式是支持大量细粒度对象的复用,所以享元模式要求被共享的对象必须是细粒度对象。
  • 享元模式的两个概念:内部状态,外部状态
  • 内部状态: 在享元对象内部不随外界环境改变而改变的共享部分
  • 外部状态:随着环境的变化而变化,不能共享的状态就是外部状态
  • 由于享元模式区分了内部状态和外部状态,所以我们可以《通过设置不同的外部状态》使得相同的对象可以具备一些不同的特性,《内部状态存储于享元对象内部,而外部状态则应该由客户端来考虑》

模式结构

  • Flyweight: 抽象享元类,所有具体享元类的超类或接口,通过这个接口可以接受并作用于外部专题

  • ConcreteFlyweight: 具体的享元类,指定内部状态,为内部状态增加存储空间

  • UnsharedConcreteFlyweight: 非共享具体享元类,指出哪些不需要共享的Flyweight子类

  • FlyweightFactory:开辟静态存储,用来创建并管理flyweight对象,它主要用于确保合理地共享Flyweight,当用户请求一个Flyweight的时候,FlyweightFactotry就会提供一个已经创建的Flyweight对象或者新建一个(如果不存在)

优点

享元模式的优点在于她能够极大的减少系统中对象的个数

享元模式由于使用了外部状态,外部状态相对独立,不会影响内部状态,所以享元对象能够在不同的环境共享

缺点

由于享元模式区分内外部状态,使的程序更加复杂了

为了使对象共享,享元模式需要将享元对象状态外部化,而读取外部状态使得运行时间变长

使用场景

如果一个系统中存在大量的相同或者相似的对象,由于这类对象的大量使用,会造成系统内存耗费,可以使用享元模式来减少系统中对象的数量

对象大部分状态都可以外部化,可以将这些外部状态传入对象中

总结

享元模式的优点在于她能够极大的减少系统中对象的数量,但它可能会引起系统逻辑更加复杂化

享元模式的核心在于享元工厂,它主要用来确保合理地共享享元对象

内部状态为不共享部分,储存于享元对象内部,而外部状态是可变部分,它应当由客户端负责

JDK源码

//测试类
public class IntegerTest {
    public static void main(String[] args) {
        Integer a = Integer.valueOf(127);
        Integer b = Integer.valueOf(127);
        System.out.println("a == b : " + (a == b));//输出true

        Integer c = Integer.valueOf(128);
        Integer d = Integer.valueOf(128);
        System.out.println("c == d : " + (c == d)); //输出false
    }
}
//源码
public final class Integer extends Number implements Comparable<Integer> {
  public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

  private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }
}

相关推荐

  1. 设计模式结构设计模式——模式

    2024-03-20 10:22:04       19 阅读
  2. 设计模式结构设计模式模式

    2024-03-20 10:22:04       8 阅读
  3. GO设计模式——13、模式结构

    2024-03-20 10:22:04       37 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-20 10:22:04       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-20 10:22:04       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-20 10:22:04       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-20 10:22:04       18 阅读

热门阅读

  1. 单例模式的两种方法:饥汉模式和懒汉模式

    2024-03-20 10:22:04       18 阅读
  2. CSS实现点击防抖

    2024-03-20 10:22:04       20 阅读
  3. 原型,模板,策略,适配器模式

    2024-03-20 10:22:04       16 阅读
  4. 设计模式(结构型设计模式——适配器模式)

    2024-03-20 10:22:04       16 阅读
  5. flink启动错误(使用YARN)

    2024-03-20 10:22:04       20 阅读
  6. HttpClient4基础

    2024-03-20 10:22:04       21 阅读
  7. Oracle中使用coe_load_sql_profile脚本固定执行计划

    2024-03-20 10:22:04       22 阅读