GOF 23設計模式之 享元模式(FlyWeight)

場景:

  • 內存屬於稀缺資源,不要隨便浪費。如果遊很多個完全相同或類似的對象,我們可以通過享元模式,節省內存。

核心

  • 享元模式以共享的方式高效地支持大量細粒度對象的重用。
  • 享元對象能做到共享的關鍵是區分了內部狀態和外部狀態。
    • 內部狀態:可以共享,不會隨環境變化而變化
    • 外部狀態:不可以共享,會隨環境變化而變化

圍棋軟件設計

  • 每個棋子都是一個對象,有如下屬性
    1. 顏色
    2. 形狀
    3. 大小
    4. 位置
  • 其中1,2,3這些是可以共享的,稱之爲:內部狀態
  • 4 是不可以共享的,稱之爲外部狀態

享元模式實現:

  • FlyweightFactory享元工廠類
    • 創建並管理享元對象,享元池一般設計成鍵值對。
  • FlyWeight抽象享元類
    • 通常是一個接口或者抽象類,聲明公共方法,這些方法可以向外界提供對象的內部狀態,設置外部狀態。
  • ConcreteFlyWeight具體享元類
    • 爲內部狀態提供給成員變量進行存儲
  • UnsharedConcreteFlyWeight非共享享元類
    • 不能被共享的子類可以設計爲非共享享元類

享元模式實現的UML圖

這裏寫圖片描述

享元模式在開發中使用的場景:

  • 享元模式由於其共享的特性,可以在任何“池”中操作,比如:線程池、數據連接池。
  • String類的設計也是享元模式

優點

  • 極大的減少了內存中對象的數量
  • 相同或相似對象內存中只有一份,極大的節約資源,提高系統性能
  • 外部狀態相對獨立,不影響內部狀態。

優點

  • 模式較爲複雜,使程序邏輯複雜化
  • 爲了節省內存,共享了內部狀態,分離了外部狀態,而讀取外部狀態使運行時間變長。用時間換取了空間。

一種實現

  • ChessFlyWeight
package com.coderbean.flyweight;

/**
 * 享元類
 * Created by Chang on 15/10/2.
 */
public interface ChessFlyWeightt {
    void setColor(String color);
    String getColor();
    void display(Coordinate c);
}


class ConcreteChess implements ChessFlyWeightt {

    private String color;

    public ConcreteChess(String color) {
        this.color = color;
    }

    @Override
    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String getColor() {
        return this.color;
    }

    @Override
    public void display(Coordinate c) {
        System.out.println("棋子顏色"+ this.color);
        System.out.println("棋子位置"+ c.getX()+"---"+c.getY());
    }
}
  • ChessFlyWeightFactory
package com.coderbean.flyweight;

import java.util.HashMap;
import java.util.Map;

/**
 * 享元工廠類
 * Created by Chang on 15/10/2.
 */
public class ChessFlyWeightFactory {
    private static Map<String, ChessFlyWeightt> map = new HashMap<String,ChessFlyWeightt>();

    public static ChessFlyWeightt getChess(String color) {
        if(map.get(color) != null) {
            return map.get(color);
        }else{
            ChessFlyWeightt cfw = new ConcreteChess(color);
            map.put(color, cfw);
            return cfw;
        }
    }
}
  • Coordinate
package com.coderbean.flyweight;

/**
 * 外部狀態UnSharedConcreteFlyWeight
 * Created by Chang on 15/10/2.
 */
public class Coordinate {
    private int x,y;

    public Coordinate(int y, int x) {
        this.y = y;
        this.x = x;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}
  • Client
package com.coderbean.flyweight;

/**
 * Created by Chang on 15/10/2.
 */
public class Client {
    public static void main(String[] args) {
        ChessFlyWeightt chess1 = ChessFlyWeightFactory.getChess("Black");
        ChessFlyWeightt chess2 = ChessFlyWeightFactory.getChess("Black");
        System.out.println(chess1);
        System.out.println(chess2);

        System.out.println("增加外部狀態的處理=======");
        chess1.display(new Coordinate(10,10));
        chess2.display(new Coordinate(100,20));
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章