Design Pattern 简明教程
Design Patterns - Flyweight Pattern
享元模式主要用于减少创建的对象的数量,减少内存占用量和提高性能。此类设计模式归属于结构模式,因为这种模式提供了减少对象数量的方法,从而改善了应用程序的对象结构。
Flyweight pattern is primarily used to reduce the number of objects created and to decrease memory footprint and increase performance. This type of design pattern comes under structural pattern as this pattern provides ways to decrease object count thus improving the object structure of application.
享元模式尝试通过存储已经存在的相似类型对象来重新使用它们,并且在找不到匹配对象时创建新对象。我们将通过绘制 20 个位于不同位置的圆圈来展示此模式,但是我们只创建 5 个对象。仅有 5 种颜色可用,因此颜色属性用于检查已经存在的 Circle 对象。
Flyweight pattern tries to reuse already existing similar kind objects by storing them and creates new object when no matching object is found. We will demonstrate this pattern by drawing 20 circles of different locations but we will create only 5 objects. Only 5 colors are available so color property is used to check already existing Circle objects.
Implementation
我们将创建一个 Shape 接口和具体类 Circle 来实现 Shape 接口。工厂类 ShapeFactory 被定义为下一步。
We are going to create a Shape interface and concrete class Circle implementing the Shape interface. A factory class ShapeFactory is defined as a next step.
ShapeFactory 拥有一个 Circle 的 HashMap,其中键是 Circle 对象的颜色。每当请求 ShapeFactory 创建特定颜色的圆圈时,它检查其 HashMap 中的圆圈对象,如果找到 Circle 对象,则返回该对象,否则创建一个新对象,将其存储在 HashMap 中以备将来使用,然后返回该对象给客户端。
ShapeFactory has a HashMap of Circle having key as color of the Circle object. Whenever a request comes to create a circle of particular color to ShapeFactory, it checks the circle object in its HashMap, if object of Circle found, that object is returned otherwise a new object is created, stored in hashmap for future use, and returned to client.
FlyWeightPatternDemo,我们的演示类,将使用 ShapeFactory 来获取 Shape 对象。它将信息(红色/绿色/蓝色/黑色/白色)传递给 ShapeFactory,以获取所需颜色的圆圈。
FlyWeightPatternDemo, our demo class, will use ShapeFactory to get a Shape object. It will pass information (red / green / blue/ black / white) to ShapeFactory to get the circle of desired color it needs.
Step 2
创建实现相同界面的具体类。
Create concrete class implementing the same interface.
Circle.java
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);
}
}
Step 3
根据给定的信息创建一个生成具体类对象的工厂。
Create a factory to generate object of concrete class based on given information.
ShapeFactory.java
import java.util.HashMap;
public class ShapeFactory {
// Uncomment the compiler directive line and
// javac *.java will compile properly.
// @SuppressWarnings("unchecked")
private static final HashMap 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;
}
}
Step 4
使用工厂,通过传递诸如颜色之类的信息来获取具体类的对象。
Use the factory to get object of concrete class by passing an information such as color.
FlyweightPatternDemo.java
public class FlyweightPatternDemo {
private static final String colors[] = { "Red", "Green", "Blue", "White", "Black" };
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);
}
}
Step 5
验证输出。
Verify the output.
Creating circle of color : Black
Circle: Draw() [Color : Black, x : 36, y :71, radius :100
Creating circle of color : Green
Circle: Draw() [Color : Green, x : 27, y :27, radius :100
Creating circle of color : White
Circle: Draw() [Color : White, x : 64, y :10, radius :100
Creating circle of color : Red
Circle: Draw() [Color : Red, x : 15, y :44, radius :100
Circle: Draw() [Color : Green, x : 19, y :10, radius :100
Circle: Draw() [Color : Green, x : 94, y :32, radius :100
Circle: Draw() [Color : White, x : 69, y :98, radius :100
Creating circle of color : Blue
Circle: Draw() [Color : Blue, x : 13, y :4, radius :100
Circle: Draw() [Color : Green, x : 21, y :21, radius :100
Circle: Draw() [Color : Blue, x : 55, y :86, radius :100
Circle: Draw() [Color : White, x : 90, y :70, radius :100
Circle: Draw() [Color : Green, x : 78, y :3, radius :100
Circle: Draw() [Color : Green, x : 64, y :89, radius :100
Circle: Draw() [Color : Blue, x : 3, y :91, radius :100
Circle: Draw() [Color : Blue, x : 62, y :82, radius :100
Circle: Draw() [Color : Green, x : 97, y :61, radius :100
Circle: Draw() [Color : Green, x : 86, y :12, radius :100
Circle: Draw() [Color : Green, x : 38, y :93, radius :100
Circle: Draw() [Color : Red, x : 76, y :82, radius :100
Circle: Draw() [Color : Blue, x : 95, y :82, radius :100