什么是享元模式
享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享对象来减少内存使用,从而提高性能。它主要用于处理大量细粒度对象的情况,通过将这些对象的可共享部分(内部状态)集中起来存储,以便多个对象可以共享这些部分,从而节省内存。
享元模式的特点
-
共享内部状态:享元模式中的对象将内部状态分为共享的和非共享的。共享的内部状态是可以在多个对象之间共享的,例如颜色、形状等,这些状态通常存储在享元工厂中,并由多个享元对象共享。
-
外部状态:非共享的状态称为外部状态,它通常是每个对象的独特状态,在使用享元对象时由客户端提供。
-
享元工厂:享元模式通常通过一个享元工厂来创建和管理享元对象。工厂会检查对象是否已经存在,如果已经存在,就返回现有对象;如果不存在,则创建一个新对象。
-
对象池:享元工厂通常使用一个对象池来存储共享的对象,以便复用这些对象。
应用场景
- 当应用程序需要处理大量细粒度对象时。
- 对象的大量创建会导致内存消耗过多。
- 对象的可共享状态可以提取出来,并在多个对象之间共享。
- 外部状态可以从对象中移出,并传递给享元对象的客户端。
优点
- 节省内存:通过共享对象,减少了对象的数量,从而节省了内存。
- 提高性能:由于对象的复用,减少了对象的创建和销毁,提高了性能。
缺点
- 需要仔细分析哪些状态可以共享,否则可能导致代码复杂。
- 如果外部状态处理不当,可能会导致线程安全问题。
举个例子
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