结构型模式6.享元模式
结构型模式
- 适配器模式(Adapter Pattern)
- 桥接模式(Bridge Pattern)
- 组合模式(Composite Pattern)
- 装饰器模式(Decorator Pattern)
- 外观模式(Facade Pattern)
- 享元模式(Flyweight Pattern)
- 代理模式(Proxy Pattern)
享元模式(Flyweight Pattern)是一种结构型设计模式,用于减少内存占用,特别是在需要创建大量相似对象的场景中。它通过共享对象来减少内存的消耗,避免创建重复的对象。
享元模式的核心思想:
享元模式的核心思想是:
- 将对象的状态分为共享状态和非共享状态。
- 共享状态存储在享元对象中,多个对象可以共享同一个享元对象。
- 非共享状态由每个具体的对象自己保存,通常是通过外部传入的方式。
享元模式的关键组成部分:
- Flyweight(享元接口):定义可以共享的接口。
- ConcreteFlyweight(具体享元类):实现共享状态。
- FlyweightFactory(享元工厂类):管理享元对象的创建和共享,确保多个对象共享相同的享元。
- UnsharedConcreteFlyweight(非共享享元类):存储每个对象独有的状态。
享元模式的例子:图形编辑器
我们可以通过一个图形编辑器的例子来说明享元模式。假设我们有一个应用需要大量绘制相同类型的图形(如圆形、方形等),但是每个图形的颜色和位置是不同的。如果每个图形都存储相同的颜色、形状等属性,那么会消耗大量内存。
为了节省内存,我们可以使用享元模式,避免为每个图形重复存储相同的信息,而是共享相同的图形数据。
public interface Shape {
void draw(String color); // 绘制图形,color是每个图形的非共享状态
}
public class Circle implements Shape {
private String shapeType; // 共享状态:形状类型
public Circle() {
this.shapeType = "Circle"; // 所有圆形对象共享同一个类型
}
@Override
public void draw(String color) {
System.out.println("绘制 " + shapeType + ",颜色: " + color);
}
}
import java.util.HashMap;
import java.util.Map;
public class ShapeFactory {
private Map<String, Shape> shapeMap = new HashMap<>(); // 缓存已经创建的享元对象
public Shape getShape(String shapeType) {
Shape shape = shapeMap.get(shapeType); // 如果已经创建过该形状,直接返回
if (shape == null) {
if (shapeType.equalsIgnoreCase("Circle")) {
shape = new Circle(); // 创建一个新的Circle对象
}
shapeMap.put(shapeType, shape); // 缓存新创建的享元对象
}
return shape;
}
}
public class Client {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
// 创建并绘制不同颜色的圆形
Shape circle1 = shapeFactory.getShape("Circle");
circle1.draw("红色");
Shape circle2 = shapeFactory.getShape("Circle");
circle2.draw("蓝色");
Shape circle3 = shapeFactory.getShape("Circle");
circle3.draw("绿色");
// 检查是否是同一个Circle对象
System.out.println(circle1 == circle2); // 输出:true,说明共享了同一个对象
}
}
解释:
- 共享状态:在这个例子中,
Circle
类的shapeType
("Circle")是共享状态,所有的圆形对象都共享同一个Circle
对象。 - 非共享状态:每个
draw
方法的color
参数是非共享状态,每个对象的颜色不同,因此存储在外部传入。 - 享元工厂(
ShapeFactory
):负责管理享元对象的创建和共享。它确保相同的形状对象(例如圆形)不会被重复创建,而是通过缓存池重用已创建的对象。 - 客户端(
Client
):客户端通过享元工厂获取图形对象,客户端并不关心这些图形是否被共享,只需要关注它们的非共享属性(如颜色)。
优势:
- 节省内存:通过共享相同的享元对象,可以大大减少内存的使用,特别是在需要创建大量相似对象的场景中。
- 提高性能:共享对象可以减少对象的创建和销毁,提高性能。
- 适用于不可变对象:享元模式特别适合用于不可变对象,因为它们的共享状态不能被修改。
劣势:
- 复杂性增加:引入享元模式后,系统的结构会变得更复杂,需要管理享元对象的创建和缓存。
- 非共享状态管理:对于每个享元对象的非共享状态,仍然需要额外的管理机制。
总结:
享元模式通过将共享状态提取出来,减少内存消耗,适用于大量相似对象的场景。在设计时需要仔细分离共享和非共享状态,确保享元对象的高效利用。