享元模式,主要就是一种池化方案,主要用于创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
享元模式,尝试重用现有的同类对象,如果未找到相同匹配的对象,那么就去创建对象。享元模式的核心思想是共享相同状态的对象,以节省系统资源和内存空间。
在享元模式中,对象分为两种类型:内部状态(Intrinsic State)和外部状态(Extrinsic State)。
内部状态是对象可以共享的不变数据,而外部状态是随着对象上下文的变化而变化的数据。通过将内部状态和外部状态分离,享元模式使得多个对象可以共享相同的内部状态,而外部状态则可以在运行时设置。
使用享元模式的主要目的是在系统中有大量对象并且这些对象的大部分状态是相同的情况下,减少对象的数量,节省内存空间,并提高系统的性能。通过共享相同状态的对象,可以避免重复创建相似的对象,从而减少内存占用。这对于需要创建大量细粒度的对象的场景特别有用,例如富文本编辑器中的字母对象、游戏中的粒子系统等。
public interface Shape {
void draw();
}
public class Circle implements Shape {
private String color;
private int x;
private int y;
private int radius;
public Circle(String color){
this.color = color;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setRadius(int radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Circle: Draw() [Color : " + color
+", x : " + x +", y :" + y +", radius :" + radius);
}
}
public class ShapeFactory {
//享元
private static final HashMap<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("Creating circle of color : " + color);
}
return circle;
}
}
public class FlyweightPatternDemo {
private static final String colors[] = { "Red", "Green", "Blue", "White", "Black" };
/**
我们将创建一个 Shape 接口和实现了 Shape 接口的实体类 Circle。下一步是定义工厂类 ShapeFactory。
ShapeFactory 有一个 Circle 的 HashMap,其中键名为 Circle 对象的颜色。无论何时接收到请求,都会创建一个特定颜色的圆。
ShapeFactory 检查它的 HashMap 中的 circle 对象,如果找到 Circle 对象,则返回该对象,否则将创建一个存储在 hashmap 中以备后续使用的新对象,并把该对象返回到客户端。
FlyWeightPatternDemo 类使用 ShapeFactory 来获取 Shape 对象。它将向 ShapeFactory 传递信息(red / green / blue/ black / white),以便获取它所需对象的颜色
*/
public static void main(String[] args) {
for(int i=0; i < 20; ++i) {
Circle circle = (Circle) ShapeFactory.getCircle(getRandomColor());
circle.setX(getRandomX());
circle.setY(getRandomY());
circle.setRadius(100);
circle.draw();
}
}
private static String getRandomColor() {
return colors[(int)(Math.random()*colors.length)];
}
private static int getRandomX() {
return (int)(Math.random()*100 );
}
private static int getRandomY() {
return (int)(Math.random()*100);
}
}
总结来说,享元模式的意图是通过共享对象的方式有效地支持大量细粒度的对象,减少对象的创建和内存占用。它可以提高系统的性能和资源利用率。使用该模式时,需要将对象的内部状态和外部状态进行合理划分,确保内部状态是可以共享的,而外部状态可以在运行时设置。
好处:
这样可以实现对象的共享,避免重复创建相似的对象,从而达到节省内存的目的。