1. 程式人生 > >設計模式的藝術 結構性模式之享元模式

設計模式的藝術 結構性模式之享元模式

前言

知道圍棋的都知道圍棋有兩種顏色的棋子,黑色和白色,不同的地方就在於他們所放置的位置不同,大體是一樣的,所以廠家生產的時候也就是批量的進行生產,反正棋子放哪他們並不需要操心,在計算機中也會存在著很多相似的物件,如果相同的物件太多將導致系統執行代價過高,記憶體屬於計算機稀缺資源,不能隨便浪費,是否有一種技術能夠節約記憶體使用空間呢?實現對這些相同或者相似的物件的共同訪問呢?答案是肯定的,這種技術就是享元模式

什麼是享元模式 Flyweight Pattern

運用共享技術有效的支援大量細粒度物件的複用,系統只使用少量的物件,而這些物件都很相似,狀態變化可以很小,可以實現物件的多次複用,由於享元模式要求能夠共享的物件必須是細粒度的物件,因此它又被稱之為輕量級模式,是一種物件結構型模式

享元模式的優點

(1)、可以極大減少記憶體中物件的數量,使得相同或相似物件在記憶體中只儲存一份,從而可以節約系統資源,提高系統性能。

(2)、享元模式的外部狀態相對獨立,而且不會影響其內部狀態,從而使得享元物件可以在不同的環境中被共享。

享元模式的缺點

(1)、享元模式使得系統變得複雜,需要分離出內部狀態和外部狀態,這使得程式的邏輯複雜化。

(2)、為了使物件可以共享,享元模式需要將享元物件的部分狀態外部化,而讀取外部狀態使得執行時間變長。

享元模式的適用場景

(1)、一個系統有大量相同或者相似的物件,造成記憶體的大量耗費

(2)、物件的大部分狀態都可以外部化,可以將這些外部狀態傳入物件之中

(3)、在使用享元模式時需要維護一個儲存享元物件的享元池,而這需要耗費一定的系統資源,因此,在需要多次重複使用享元物件時才值得使用享元模式

享元模式的具體實現

目錄結構

抽象享元類

package com.company;

//圍棋棋子類:抽象享元類
public abstract class IgoChessman {
    public abstract String getColor();

    public void display(Coordinates coordinates) {
        System.out.println("棋子顏色是:" + this.getColor()+",棋子的位置:"+coordinates.getX()
        +","+coordinates.getY());

    }

}

具體享元類

package com.company;

//黑色棋子類:具體享元類
public class BlackIgoChessman extends IgoChessman {
    @Override
    public String getColor() {
        return "黑色";
    }
}
package com.company;

//白色棋子類:具體享元類
public class WhiteIgoChessman extends IgoChessman {
    @Override
    public String getColor() {
        return "白色";
    }
}

享元工廠類

package com.company;

import java.util.Hashtable;

//圍棋棋子工廠類:享元工廠類,使用單例模式進行設計
public class IgoChessmanFactory  {
    private static IgoChessmanFactory instance=new IgoChessmanFactory();
    private static Hashtable ht; //使用hashtable物件儲存享元物件,充當享元池
    private IgoChessmanFactory(){
        ht=new Hashtable();
        IgoChessman black,white;
        black=new BlackIgoChessman();
        ht.put("b",black);
        //白色
        white=new WhiteIgoChessman();
        ht.put("w",white);
    }
    //返回享元工廠類的唯一例項
    public static IgoChessmanFactory getInstance(){
        return  instance;
    }
    //通過key來獲取儲存在Hashtable中的享元物件
    public  IgoChessman getIgoChessman(String color){
        return  (IgoChessman) ht.get(color);
    }
}

外部狀態類

package com.company;

//座標類,外部狀態類
public class Coordinates {
    private int x;
    private int y;
    public Coordinates(int x,int y){
        this.x=x;
        this.y=y;
    }

    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;
    }
}

客戶端測試類

package com.company;

public class Client {

    public static void main(String[] args) {
           IgoChessman black1,black2,black3,white1,white2;
           IgoChessmanFactory factory;
           //獲取享元的物件
            factory=IgoChessmanFactory.getInstance();
            //通過享元工廠獲取三顆黑子
        black1=factory.getIgoChessman("b");
        black2=factory.getIgoChessman("b");
        black3=factory.getIgoChessman("b");
        System.out.println("判斷兩顆黑子是否相同"+(black1==black2));
        //通過享元工廠獲取兩顆白子
        white1=factory.getIgoChessman("w");
        white2=factory.getIgoChessman("w");
        System.out.println("判斷兩顆白字是否相同"+(white1==white2));
        //顯示棋子
        black1.display(new Coordinates(1,2));
        black2.display(new Coordinates(2,2));
        black3.display(new Coordinates(3,2));
        white1.display(new Coordinates(4,2));
        white2.display(new Coordinates(5,2));
    }
}

轉載請註明出處,掌聲送給社會人