设计模式——享元模式(Flyweight)

享元模式(Flyweight Pattern)是一种软件设计模式,它运用共享技术来有效地支持大量细粒度对象的复用。以下是关于享元模式的详细解释:

定义

享元模式使用共享物件,以尽可能减少内存使用量以及分享信息给尽可能多的相似物件。它特别适合用于那些因重复而导致使用大量内存的对象。通常,对象中的部分状态是可以共享的。

结构

享元模式包含以下几个主要角色:

  1. 抽象享元(Flyweight):定义了一个接口,用于描述享元对象的方法。这些方法可能包括接受并操作内蕴状态和外蕴状态。
  2. 具体享元(ConcreteFlyweight):实现了抽象享元接口,并为内蕴状态(不随环境改变而改变的状态)提供存储空间。如果有外蕴状态(随环境改变而改变的状态),则由客户端负责保存。
  3. 享元工厂(FlyweightFactory):负责创建和管理享元对象。它确保合理地共享享元,并在需要时创建新的享元。
  4. 客户端(Client):维护一个对所有享元对象的引用,存储对应的外蕴状态,并在需要时与享元对象交互。

特点

  1. 减少对象创建:通过共享已经存在的对象,享元模式可以大幅度减少需要创建的对象数量。
  2. 降低系统内存:由于减少了对象的创建,享元模式可以有效地降低系统的内存消耗。
  3. 提高系统资源利用率:通过共享和复用对象,享元模式可以提高系统资源的利用率。

使用场景

享元模式适用于以下场景:

  1. 大量共享对象的场景:如数据库连接池、线程池等,这些对象可以通过享元模式来实现共享,减少对象的创建和销毁,提高系统的性能和可扩展性。
  2. 大数据量的场景:如图像处理中的像素点、文本处理中的单词等,这些对象可以通过享元模式来共享,减少对象的创建和内存消耗。
  3. 高并发的场景:如电商网站的购物车、在线游戏的排行榜等,这些对象可以通过享元模式来共享,减少对象的创建和销毁,提高系统的并发处理能力和响应速度。
  4. 分布式系统中的对象共享:如分布式缓存系统、分布式锁等,这些对象需要在不同的节点之间共享,享元模式可以有效地支持这种共享。

示例

当然,下面是一个简单的享元模式的Java代码示例。在这个例子中,我们将创建一个Flyweight接口,一个具体的Flyweight实现类(例如ConcreteFlyweight),一个FlyweightFactory用于创建和存储Flyweight对象,以及一个Client类来展示如何使用这些对象。

// Flyweight 接口
public interface Flyweight {
    void operation(UnsharedConcreteFlyweight state);
}

// UnsharedConcreteFlyweight 类,包含外蕴状态
public class UnsharedConcreteFlyweight {
    // 外蕴状态数据
    private String extrinsicState;

    public UnsharedConcreteFlyweight(String extrinsicState) {
        this.extrinsicState = extrinsicState;
    }

    // 获取外蕴状态
    public String getExtrinsicState() {
        return extrinsicState;
    }
}

// ConcreteFlyweight 类,实现Flyweight接口,包含内蕴状态
public class ConcreteFlyweight implements Flyweight {
    // 内蕴状态数据
    private String intrinsicState;

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

    // 展示内蕴状态和外蕴状态的操作
    @Override
    public void operation(UnsharedConcreteFlyweight state) {
        System.out.println("Intrinsic State: " + intrinsicState);
        System.out.println("Extrinsic State: " + state.getExtrinsicState());
    }
}

// FlyweightFactory 类,用于存储和创建Flyweight对象
public class FlyweightFactory {
    // 享元对象的存储
    private static Map<String, Flyweight> flyweights = new HashMap<>();

    // 获取Flyweight对象
    public static Flyweight getFlyweight(String key) {
        Flyweight flyweight = flyweights.get(key);
        if (flyweight == null) {
            flyweight = new ConcreteFlyweight(key);
            flyweights.put(key, flyweight);
        }
        return flyweight;
    }
}

// Client 类,客户端代码
public class Client {
    public static void main(String[] args) {
        // 外蕴状态
        UnsharedConcreteFlyweight extrinsicStateA = new UnsharedConcreteFlyweight("Extrinsic A");
        UnsharedConcreteFlyweight extrinsicStateB = new UnsharedConcreteFlyweight("Extrinsic B");

        // 获取享元对象
        Flyweight flyweightA = FlyweightFactory.getFlyweight("Intrinsic A");
        Flyweight flyweightB = FlyweightFactory.getFlyweight("Intrinsic B");

        // 展示操作
        flyweightA.operation(extrinsicStateA);
        flyweightB.operation(extrinsicStateB);

        // 再次使用相同的内蕴状态
        Flyweight flyweightA_again = FlyweightFactory.getFlyweight("Intrinsic A");
        // 注意这里flyweightA_again和flyweightA是同一个对象
        System.out.println("flyweightA == flyweightA_again: " + (flyweightA == flyweightA_again));
    }
}

在这个例子中,Flyweight接口定义了一个操作,该操作需要一个UnsharedConcreteFlyweight对象作为参数(这代表了外蕴状态)。ConcreteFlyweight类实现了Flyweight接口,并存储了内蕴状态。FlyweightFactory类负责创建和存储Flyweight对象,它使用了一个Map来存储已经创建的享元对象。在Client类中,我们展示了如何使用FlyweightFactory来获取享元对象,并调用其操作。注意,当使用相同的内蕴状态再次请求享元对象时,FlyweightFactory将返回已经存在的对象。

相关推荐

  1. 设计模式--模式Flyweight Pattern)

    2024-05-11 05:40:03       41 阅读
  2. 设计模式】11、flyweight 模式

    2024-05-11 05:40:03       35 阅读
  3. 设计模式——模式Flyweight

    2024-05-11 05:40:03       36 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-11 05:40:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-11 05:40:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-05-11 05:40:03       87 阅读
  4. Python语言-面向对象

    2024-05-11 05:40:03       96 阅读

热门阅读

  1. C 标准库 - <stdlib.h>

    2024-05-11 05:40:03       30 阅读
  2. ~MAY~

    2024-05-11 05:40:03       31 阅读
  3. Python注释

    2024-05-11 05:40:03       29 阅读
  4. 006 springCloudAlibaba seata

    2024-05-11 05:40:03       24 阅读
  5. 2、TS中的基础讲解

    2024-05-11 05:40:03       29 阅读
  6. Transformer优化加速--xformers

    2024-05-11 05:40:03       32 阅读
  7. tengine-docker镜像制作

    2024-05-11 05:40:03       33 阅读
  8. docker部署go项目

    2024-05-11 05:40:03       30 阅读