java设计模式之-享元模式
什么是享元模式?
享元模式是一种结构型设计模式,旨在通过共享对象来最大程度地减少内存使用和提高性能。它通过将对象的状态分为内部状态和外部状态,将可共享的内部状态存储在对象池中,并在需要时共享给多个对象,从而减少了重复创建相似对象的成本。主要解决什么问题?
享元模式主要解决大量细粒度对象的内存消耗问题。在某些情况下,如果每个对象都独立地存储了大量相似的数据,将导致内存消耗过高。通过共享对象,我们可以显著减少内存使用,提高系统的整体性能。在什么时候我们需要使用享元模式?
当满足以下条件时,考虑使用享元模式:
系统中存在大量相似的对象。
创建这些对象的开销很大,导致内存消耗过高。
对象的状态可以被分为内部状态和外部状态,其中内部状态可以被共享。
用一个生活中的应用实例来举例、类比
假设您正在开发一个绘图应用程序,用户可以绘制各种形状(如圆形、矩形等)。在这种情况下,每个形状对象都有一些相同的属性,比如颜色、线条粗细等,以及一些特定于该形状的属性,比如半径、宽度和高度。在不使用享元模式的情况下,每次用户绘制一个新形状时,都会创建一个全新的对象,这将导致内存消耗增加。而使用享元模式,您可以将共享的属性(如颜色)作为内部状态存储在对象池中,每次用户绘制时,只需为特定的属性(如半径)创建一个新对象,从而减少了内存占用。优点
减少内存消耗:通过共享内部状态,减少了需要创建的对象数量,从而降低了内存消耗。
提高性能:复用现有对象可以避免频繁创建和销毁对象的开销,从而提高系统性能。
简化对象管理:享元模式将对象的状态分为内部状态和外部状态,简化了对象的管理和维护。
缺点
引入了对象共享,可能会增加系统的复杂性。
对象共享可能会导致线程安全问题,需要注意并发访问的同步控制。
使用场景
享元模式适用于以下情况:
系统中存在大量相似的对象,且创建这些对象的开销较大。
对象的大部分状态可以被外部化,剩余部分可以通过共享实现。
下面是一个简单的Java代码示例:
import java.util.HashMap;
import java.util.Map;
// 图形接口
interface Shape {
void draw();
}
// 具体图形类
class Circle implements Shape {
private String color;
public Circle(String color) {
this.color = color;
}
public void draw() {
System.out.println("绘制了一个" + color + "的圆形");
}
}
// 图形工厂类
class ShapeFactory {
private static final Map<String, Shape> circleMap = new HashMap<>();
public static Shape getCircle(String color) {
Circle circle = (Circle) circleMap.get(color);
if (circle == null) {
circle = new Circle(color);
circleMap.put(color, circle);
System.out.println("创建了一个" + color + "的圆形");
} else {
System.out.println("获取了一个" + color + "的圆形");
}
return circle;
}
}
// 示例代码
public class Main {
public static void main(String[] args) {
String[] colors = {"红色", "绿色", "蓝色", "红色"};
for (String color : colors) {
Shape shape = ShapeFactory.getCircle(color);
shape.draw();
}
}
}
在上述示例中,Circle
表示具体的圆形对象,ShapeFactory
是图形工厂类,负责创建和管理圆形对象。ShapeFactory
使用 circleMap
字典来缓存已创建的圆形对象。当需要获取一个圆形对象时,首先在字典中查找是否存在对应颜色的圆形对象,如果存在则返回已有的对象,否则创建一个新的圆形对象并将其添加到字典中。
当运行示例代码时,可以看到只有第一次创建圆形对象时会输出"创建了一个颜色的圆形",后续获取相同颜色的圆形对象时会输出"获取了一个颜色的圆形"。这说明通过享元模式,我们成功地实现了圆形对象的共享,减少了对象的创建和内存消耗。