Java設計模式11——享元模式
一、適用場景
記憶體屬於稀缺資源,不能隨意浪費。如果在一個系統中有很多個完全相同或相似的物件,我們就可以使用享元模式,讓他們共享一份記憶體即可,不必每個都去例項化物件,從而節省記憶體空間。
二、模式核心
- 享元模式以共享的方式高效的支援大量細粒度物件的重用。
- 享元物件能做到共享的關鍵是區分了內部狀態和外部狀態。
- 內部狀態:可以共享,不會隨環境改變而改變。
- 外部狀態:不可以共享,會隨環境改變而改變。
圍棋例子:
每一個圍棋棋子都是一個物件,並都有如下屬性:
三、享元模式結構
UM類圖:
- FlyWeight抽象享元類:通常是一個介面或抽象類,宣告公共方法,這些方法可以向外界提供物件的內部狀態,設定外部狀態。
- UnsharedConcreteFlyWeight非共享享元類:不能被共享的子類可以設計為非共享享元類。
ConcreteFlyWeight具體享元類:為內部狀態提供成員變數進行儲存。
FlyWeightFactory享元工廠類:建立並管理享元物件,享元池一般設計為鍵值對。
圍棋程式碼示例:
FlyWeight抽象享元類:
public interface ChessFlyWeight {
String getColor();//獲取顏色,內部狀態
void display(Coordinate c);//展示位置,外部狀態
}
UnSharedConcreteFlyweight 非共享享元類:
/**
* 外部狀態:棋子座標位置
*/
public class Coordinate {
private int x,y;
public Coordinate(int x, int y) {
super();
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;
}
}
ConcreteFlyWeight具體享元類:
class ConcreteChess implements ChessFlyWeight{
private String color;
public ConcreteChess(String color) {
super();
this.color = color;
}
public String getColor() {
return color;
}
public void display(Coordinate c) {
System.out.println("棋子顏色:"+color);
System.out.println("棋子位置"+c.getX()+"-----"+c.getY());
}
}
FlyWeightFactory享元工廠
public class ChessFlyWeightFactory {
//享元池
private static Map<String,ChessFlyWeight> map=new HashMap<String,ChessFlyWeight>();
public static ChessFlyWeight getChess(String color){
if(map.get(color)!=null){
return map.get(color);
}else{
ChessFlyWeight cfw=new ConcreteChess(color);
map.put(color, cfw);
return cfw;
}
}
}
客戶端
public class Client {
public static void main(String[] args) {
ChessFlyWeight chess1=ChessFlyWeightFactory.getChess("黑色");
ChessFlyWeight chess2=ChessFlyWeightFactory.getChess("黑色");
System.out.println(chess1);
System.out.println(chess2);
System.out.println("-----增加外部狀態的處理----");
chess1.display(new Coordinate(10,10));
chess2.display(new Coordinate(20,20));
}
}
//輸出結果
flyweight.ConcreteChess@15db9742
flyweight.ConcreteChess@15db9742
-----增加外部狀態----
棋子顏色:黑色
棋子位置10-----10
棋子顏色:黑色
棋子位置20-----20
從上面的輸出結果可看出chess1,chess2兩個物件使用的是同一個記憶體空間,即它們是同一例項。
在JAVA語言中,String型別就是使用了享元模式。String物件是final型別,物件一旦建立就不可改變。在JAVA中字串常量都是存在常量池中的,JAVA會確保一個字串常量在常量池中只有一個拷貝。String a=”abc”,其中”abc”就是一個字串常量。
四、總結
優點:
- 極大減少記憶體中物件的數量。
- 相同或相似的物件記憶體只保持一份,極大的節約資源,提高系統效能。
- 外部狀態相對獨立,不影響內部變化。
缺點:
- 模式較複雜,使程式邏輯複雜化。
- 為了節省記憶體,共享了內部狀態,分離出了外部狀態,而讀取外部狀態使執行時間變長。用時間換空間。
相關文章
- 11.java設計模式之享元模式Java設計模式
- Java設計模式之(十一)——享元模式Java設計模式
- Java學設計模式之享元模式Java設計模式
- 設計模式----享元模式設計模式
- 設計模式-享元模式設計模式
- Java設計模式(13):享元模式(蠅量模式)Java設計模式
- Java設計模式之七 —– 享元模式和代理模式Java設計模式
- 設計模式之享元模式設計模式
- javascript設計模式享元模式JavaScript設計模式
- 設計模式(十七):享元模式設計模式
- 設計模式系列13–享元模式設計模式
- 極簡設計模式-享元模式設計模式
- Python設計模式-享元模式Python設計模式
- iOS設計模式 (四)享元模式iOS設計模式
- 軟體設計模式————(享元模式)設計模式
- 好程式設計師分享java設計模式之享元模式程式設計師Java設計模式
- 好程式設計師精講 java設計模式—享元模式程式設計師Java設計模式
- C#設計模式(13)——享元模式C#設計模式
- 設計模式系列13--享元模式設計模式
- C#設計模式之享元模式C#設計模式
- 通俗 Python 設計模式——享元模式Python設計模式
- 我學設計模式 之 享元模式設計模式
- Java進階篇設計模式之七 —– 享元模式和代理模式Java設計模式
- Java進階篇設計模式之七 ----- 享元模式和代理模式Java設計模式
- 《設計模式四》觀察、組合、享元模式設計模式
- 設計模式【10】-- 順便看看享元模式設計模式
- 設計模式 | 享元模式及典型應用設計模式
- 10、Python與設計模式–享元模式Python設計模式
- 12.享元模式設計思想模式
- 每天一個設計模式之享元模式設計模式
- 軟體設計模式系列之十三——享元模式設計模式
- 設計模式--享元模式FlyWeight(結構型)設計模式
- C#設計模式系列:享元模式(Flyweight)C#設計模式
- 設計模式(十六)----結構型模式之代理享元模式設計模式
- 無廢話設計模式(9)結構型模式--享元模式設計模式
- Rust語言之GoF設計模式:Flyweight享元模式RustGo設計模式
- 設計模式之:享元模式FlyweightPattern的實現設計模式
- 享元模式模式