Java 设计模式系列(十一)享元模式

Java 设计模式系列(十一)享元模式

Flyweight 享元模式是对象的结构模式。享元模式以共享的方式高效地支持大量的细粒度对象。

一、享元模式的结构

享元模式采用一个共享来避免大量拥有相同内容对象的开销。这种开销最常见、最直观的就是内存的损耗。享元对象能做到共享的关键是区分内部状态(Internal State)和外部状态(External State)。

一个内部状态是存储在享元对象内部的,并且是不会随环境的改变而有所不同。因此,一个享元可以具有内蕴状态并可以共享。

一个外部状态是随环境的改变而改变的、不可以共享的。享元对象的外蕴状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。外蕴状态不可以影响享元对象的内部状态,它们是相互独立的。

图11-1 享元模式的结构

  • Flyweight:享元接口,通过这个接口 flyweight 可以接受并作用于外部状态。通过这个接口传入外部的状态,在享元对象的方法处理中可能会使用这些外部的数据。

  • ConcreteFlyweight:具体的享元实现对象,必须是可共享的,需要封装 flyweight 的内部状态。

  • FlyweightFactory:享元工厂,主要用来创建并管理共享的享元对象,并对外提供访问共享享元的接口。

源代码

(1) Flyweight

/***
 * 享元接口,通过这个接口享元可以接受并作用于外部状态
 */
public interface Flyweight {
    /** 示例操作,传入外部状态 */
    public void operation(String extrinsicState);
}

public class ConcreteFlyweight implements Flyweight{
    /** 示例,描述内部状态 */
    private String intrinsicState;

    /** 构造方法,传入享元对象的内部状态的数据 */
    public ConcreteFlyweight(String state){
        this.intrinsicState = state;
    }

    public void operation(String extrinsicState) {
        //具体的功能处理,可能会用到享元内部、外部的状态
    }
}

(2) FlyweightFactory

/**
 * 享元工厂,说白了就是一个缓存
 */
public class FlyweightFactory {
    /** 缓存多个flyweight对象,这里只是示意一下 */
    private Map<String, Flyweight> fsMap = new HashMap<String,Flyweight>();

    /** 获取key对应的享元对象 */
    public Flyweight getFlyweight(String key) {
        //这个方法里面基本的实现步骤如下:
        //1:先从缓存里面查找,是否存在key对应的Flyweight对象
        Flyweight f = fsMap.get(key);

        //2:如果存在,就返回相对应的Flyweight对象
        if(f == null){
            //3:如果不存在
            //3.1:创建一个新的Flyweight对象
            f = new ConcreteFlyweight(key);
            //3.2:把这个新的Flyweight对象添加到缓存里面
            fsMap.put(key, f);
            //3.3:然后返回这个新的Flyweight对象
        }
        return f;
    }
}

二、总结

(1) 享元模式的优缺点

享元模式的优点在于它大幅度地降低内存中对象的数量。但是,它做到这一点所付出的代价也是很高的:

  • 享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。

  • 享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。


每天用心记录一点点。内容也许不重要,但习惯很重要!

原文地址:https://www.cnblogs.com/binarylei/p/9012173.html