Design Pattern

Chapter 10 享元模式(Flyweight Pattern)

定義

共享物件,用來儘可能減少記憶體使用量以及分享資訊給儘可能多的相似物件。

組成

  1. 抽象享元角色(Flyweight):所有的具體享元類的超類,為這些類規定出需要實現的公共接口。
  2. 具體享元角色(ConcreteFlyweight):實現Flyweight接口,並為內部狀態拉回存儲空間。
  3. 享元工廠角色(FlyweightFactory):負責創建和管理享元角色。
  4. 客戶端角色(Client):需要存儲所有享元對象的外部狀態。

程式碼

Step1

public interface Shape {
    public void draw();
}

Step2

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("圓形[顏色 : " + color + ", x : " + x +  ", y : " + y +  ", radius : " + radius + " ]");
    }
}

Step3

public class ShapeFactory {
    private static final HashMap<String, Shape> circleMap = new HashMap();

    public static Shape getCircle(String color) {
        Circle circle = (Circle) circleMap.get(color);

        circle = new Circle(color);
        circleMap.put(color, circle);
        System.out.println("建立一個圓形顏色為 : " + color);
        return circle;
    }
}

Step4

public class FlyweightPatternDemo {
    private static final String colors[] = { "Red", "Green", "Blue", "White", "Black" };

    public static void main(String[] args) {
        for (int i = 0; i < 5; ++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);
    }
}

Step5(Output)

建立一個圓形顏色為 : Green
圓形[顏色 : Green, x : 29, y : 97, radius : 100 ]
建立一個圓形顏色為 : Red
圓形[顏色 : Red, x : 52, y : 98, radius : 100 ]
建立一個圓形顏色為 : Red
圓形[顏色 : Red, x : 19, y : 80, radius : 100 ]
建立一個圓形顏色為 : White
圓形[顏色 : White, x : 3, y : 0, radius : 100 ]
建立一個圓形顏色為 : Red
圓形[顏色 : Red, x : 81, y : 39, radius : 100 ]

優點

  1. 降低內存中對象的數量。
  2. 外部狀態獨立,可使享元對象在不同環境被共享。

缺點

  1. 需要分離出內部狀態和外部狀態,使得系統變複雜。
  2. 為了使對象可以共享,享元模式需要將享元對象的狀態外部化,而讀取外部狀態使運行時間變長。