设计模式-享元模式

1.基础概念

享元模式的核心在于“共享”二字,它通过将可共享的部分(即内部状态)提取出来,仅存储一次,而对于会变化的外部状态,则在使用时传入。这样,通过享元工厂管理这些共享对象,客户端在请求时,根据具体情况获取或创建相应的享元对象,从而达到节省内存的目的。

2.享元模式的组成部分

  1. 抽象享元类:定义享元对象的接口。
  2. 具体享元类:实现抽象享元类,包含内部状态。
  3. 享元工厂类:管理享元对象的创建和检索。

3.享元模式的实现

3.1 抽象享元类

public interface Flyweight {
    void operation(int extrinsicState);
}

3.2 具体享元类

public class ConcreteFlyweight implements Flyweight {
    private String intrinsicState; // 内部状态

    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    @Override
    public void operation(int extrinsicState) {
        System.out.println("Intrinsic State: " + intrinsicState + ", Extrinsic State: " + extrinsicState);
    }
}

3.3 享元工厂类

import java.util.HashMap;
import java.util.Map;

public class FlyweightFactory {
    private Map<String, Flyweight> flyweights = new HashMap<>();

    public Flyweight getFlyweight(String key) {
        if (!flyweights.containsKey(key)) {
            Flyweight flyweight = new ConcreteFlyweight(key);
            flyweights.put(key, flyweight);
        }
        return flyweights.get(key);
    }
}

4. 使用示例

public class Main {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();
        Flyweight flyweight1 = factory.getFlyweight("A");
        flyweight1.operation(1);

        Flyweight flyweight2 = factory.getFlyweight("B");
        flyweight2.operation(2);

        Flyweight flyweight3 = factory.getFlyweight("A");
        flyweight3.operation(3);
    }
}

5. 优点

  1. 减少内存占用:通过共享技术,大幅度减少相似对象的创建,节省内存空间。
  2. 提高性能:减少对象的创建和销毁过程,提高系统性能。
  3. 简化管理:通过享元工厂集中管理享元对象,使得对象的创建、维护更加方便。

6. 缺点

  1. 设计复杂度增加:需要正确识别内部状态和外部状态,划分清晰,并处理好它们之间的关系,这增加了设计的复杂度。
  2. 不适合所有场景:对于内部状态复杂多变的对象,不适合使用享元模式,因为这会增加管理和区分状态的复杂度。
  3. 可能会引入额外的系统开销:如哈希表或其他数据结构来管理享元对象,虽然节省了内存,但可能会增加查找等操作的时间开销。

7. 结论

享元模式通过共享技术实现了大量细粒度对象的高效复用,特别适用于存在大量相似对象的场景,如字符渲染、数据库连接池等。通过区分内部状态和外部状态,享元模式在保证对象功能的同时,极大降低了内存占用,提升了系统性能。然而,它也增加了设计的复杂度,并且不是所有情况都适用,需要根据实际情况权衡利弊。