金三银四面试题(二十四):享元模式知多少?

发布于:2024-05-07 ⋅ 阅读:(26) ⋅ 点赞:(0)

什么是享元模式

享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享对象来减少内存使用,从而提高性能。它主要用于处理大量细粒度对象的情况,通过将这些对象的可共享部分(内部状态)集中起来存储,以便多个对象可以共享这些部分,从而节省内存。

享元模式的特点

  1. 共享内部状态:享元模式中的对象将内部状态分为共享的和非共享的。共享的内部状态是可以在多个对象之间共享的,例如颜色、形状等,这些状态通常存储在享元工厂中,并由多个享元对象共享。

  2. 外部状态:非共享的状态称为外部状态,它通常是每个对象的独特状态,在使用享元对象时由客户端提供。

  3. 享元工厂:享元模式通常通过一个享元工厂来创建和管理享元对象。工厂会检查对象是否已经存在,如果已经存在,就返回现有对象;如果不存在,则创建一个新对象。

  4. 对象池:享元工厂通常使用一个对象池来存储共享的对象,以便复用这些对象。

应用场景

  • 当应用程序需要处理大量细粒度对象时。
  • 对象的大量创建会导致内存消耗过多。
  • 对象的可共享状态可以提取出来,并在多个对象之间共享。
  • 外部状态可以从对象中移出,并传递给享元对象的客户端。

优点

  • 节省内存:通过共享对象,减少了对象的数量,从而节省了内存。
  • 提高性能:由于对象的复用,减少了对象的创建和销毁,提高了性能。

缺点

  • 需要仔细分析哪些状态可以共享,否则可能导致代码复杂。
  • 如果外部状态处理不当,可能会导致线程安全问题。

举个例子

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

// 享元接口
interface Flyweight {
    void operation(String externalState);
}

// 具体享元类
class ConcreteFlyweight implements Flyweight {
    private final String intrinsicState;

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

    @Override
    public void operation(String externalState) {
        System.out.println("Intrinsic state: " + intrinsicState + ", External state: " + externalState);
    }
}

// 享元工厂
class FlyweightFactory {
    private final Map<String, Flyweight> flyweights = new HashMap<>();

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

    public int getFlyweightCount() {
        return flyweights.size();
    }
}

// 客户端代码
public class FlyweightPatternDemo {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();

        // 获取享元对象并执行操作
        Flyweight flyweight1 = factory.getFlyweight("State1");
        flyweight1.operation("External1");

        Flyweight flyweight2 = factory.getFlyweight("State1");
        flyweight2.operation("External2");

        Flyweight flyweight3 = factory.getFlyweight("State2");
        flyweight3.operation("External1");

        // 显示享元对象的数量
        System.out.println("Number of flyweight objects: " + factory.getFlyweightCount());
    }
}

在这个示例中,FlyweightFactory 是享元工厂,它通过键(状态)来管理享元对象。当客户端请求一个享元对象时,工厂会返回现有对象或创建一个新对象。ConcreteFlyweight 是具体享元类,它有一个内在状态,可以在多个对象之间共享。

思考

享元模式和单例模式是如此相像,那么区别是什么?

往期推荐

金三银四面试题(二十一):代理模式知多少?2024-04-16
金三银四面试题(二十):单例模式知多少?2024-04-15
金三银四面试题(十九):MySQL中的锁2024-04-09
MySQL基础练习题:习题7-112024-04-09
金三银四面试题(十八):MySQL索引2024-04-08
MySQL基础练习题:习题4562024-04-08
金三银四面试题(十七):MySQL面试都问什么(2)2024-04-07
MySQL基础练习题:习题2-32024-04-07
MySQL基础练习题:创建数据库2024-04-07
金三银四面试题(十六):MySQL面试都问什么(1)2024-04-07

在这里插入图片描述