Structural Patterns Part 6/7: Flyweight Pattern
目录
Definition
Flyweight Pattern 主要用来减少对象的创建次数从而降低内存占用,提升性能。Flyweight Pattern试图重用一些相似的对象并且存储起来(利用Map),后续再有对象的创建请求时,先查一下Map中有没有,有的话直接返回该对象,没有的话再创建。
一句话:
Use sharing to support large numbers of fine-grained objects efficiently.
何时使用?当对象与对象之间非常相似,并且希望可以把已经创建的对象缓存起来重复使用时。
使用频率: Low
UML Class Diagram
Implementation
这里用到了围棋的例子。
棋盘上的棋子之间非常相似,除了位置不同之外就是黑白两色,如果一个棋盘上需要创建几百个对象实在是太浪费了,使用Flyweight Pattern。
// Shape.java
package designpatterns.structuralpatterns.flyweight;
public interface Shape {
void draw();
}
// ShapeImpl.java
package designpatterns.structuralpatterns.flyweight;
class Chessman implements Shape {
private int x;
private int y;
private String color;
public Chessman(String color) {
super();
this.color = color;
}
@Override
public void draw() {
if("BLACK".equalsIgnoreCase(color)){
System.out.println("●" + toString());
} else if("WHITE".equalsIgnoreCase(color)) {
System.out.println("○" + toString());
} else {
System.out.println("Black or White ?");
}
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
@Override
public String toString() {
return " [X=" + x + ", Y=" + y + ", Color=" + color + "]";
}
}
// FlyweightDemo.java
package designpatterns.structuralpatterns.flyweight;
import java.util.*;
public class FlyweightDemo {
private static final String[] colors = {"BLACK", "WHITE"};
public static void main(String[] args) {
ChessBoard cb = new ChessBoard();
for(int i = 0;i < 10; ++i) {
Chessman chessman = cb.getChessman(getRandomColor());
chessman.setX(getRandomXY());
chessman.setY(getRandomXY());
chessman.draw();
}
System.out.println("===========================");
System.out.println("Chess Type Number: " + cb.getChessTypeNum());
}
public static String getRandomColor() {
return colors[(int)(Math.random() * colors.length)];
}
public static int getRandomXY() {
return (int)(Math.random() * 100);
}
}
class ChessBoard {
private HashMap<String, Shape> chessmenMap = new HashMap<>();
public Chessman getChessman(String orogincolor) {
String color = orogincolor.toUpperCase();
Chessman chessman = (Chessman)chessmenMap.get(color);
if(null == chessman) {
chessman = new Chessman(color);
chessmenMap.put(color, chessman);
System.out.println("*** Creating a Chessman ***");
}
return chessman;
}
public int getChessTypeNum() {
return chessmenMap.size();
}
}
// output
*** Creating a Chessman ***
○ [X=9, Y=28, Color=WHITE]
*** Creating a Chessman ***
● [X=55, Y=18, Color=BLACK]
● [X=92, Y=19, Color=BLACK]
○ [X=40, Y=40, Color=WHITE]
○ [X=43, Y=75, Color=WHITE]
○ [X=84, Y=24, Color=WHITE]
● [X=85, Y=12, Color=BLACK]
○ [X=9, Y=13, Color=WHITE]
● [X=27, Y=3, Color=BLACK]
○ [X=10, Y=76, Color=WHITE]
===========================
Chess Type Number: 2