設計模式的藝術 結構性模式之享元模式
阿新 • • 發佈:2018-11-01
前言
知道圍棋的都知道圍棋有兩種顏色的棋子,黑色和白色,不同的地方就在於他們所放置的位置不同,大體是一樣的,所以廠家生產的時候也就是批量的進行生產,反正棋子放哪他們並不需要操心,在計算機中也會存在著很多相似的物件,如果相同的物件太多將導致系統執行代價過高,記憶體屬於計算機稀缺資源,不能隨便浪費,是否有一種技術能夠節約記憶體使用空間呢?實現對這些相同或者相似的物件的共同訪問呢?答案是肯定的,這種技術就是享元模式
什麼是享元模式 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));
}
}
轉載請註明出處,掌聲送給社會人