設計模式之享元模式,這樣學So Easy

設計模式之享元模式,這樣學So Easy

放鬆1秒鐘

什麼是享元模式

運用共享技術來有效地支援大量細粒度物件的複用。它透過共享已經存在的物件來最大程度減少需要建立的物件數量,避免大量相似物件的開銷,從而提高系統資源的利用率。

享元模式,也叫作蠅量模式,屬於結構型設計模式。

享元模式類圖

設計模式之享元模式,這樣學So Easy

享元模式角色

抽象享元角色(FlyWeight)

: 要求是一個抽象類或介面,宣告抽象方法,這些方法需要具體享元類來實現,並向外界提供享元物件的內部狀態資料及外部狀態資料。

具體享元角色(ConcreteFlyWeight)

: 它繼承或實現了抽象享元類,稱為享元物件,需要透過享元工廠類來提供唯一的享元物件。

非享元角色(UnshareConcreteFlyWeight)

: 不能被共享的子類可設計為非共享具體享元類,它代表了享元物件的外部狀態。非享元物件可以直接作為享元物件方法的引數進行傳遞。

享元工廠角色(FlyWeightFactory)

: 負責建立和管理享元物件,客戶端直接透過享元工廠物件來獲取所需要的享元物件。

享元模式兩種狀態

內部狀態

:不會隨環境改變而改變的可共享部分。比如圍棋的顏色就兩種(白棋、黑棋)。

外部狀態

:隨環境改變而改變的不可以共享的部分。比如圍棋的位置(也就是座標)。

享元模式優缺點

優點:

1。極大減少記憶體中共享物件的數量,節約記憶體資源,提高系統性能。

2。享元模式中外部狀態相對獨立,且不影響內部狀態。

缺點:

需要將享元物件的狀態,分離為內部狀態和外部狀態,程式邏輯變得複雜了。

享元模式demo需求

以圍棋為例,透過享元模式來實現,其中把白棋、黑棋作為具體享元類,白色、黑色是內部狀態,圍棋的座標位置是外部狀態。

享元模式原始碼示例

/**  * @ClassName AbstractGo  * @Description: 抽象享元角色:圍棋類  * @Author ford  * @Date 2021/4/29  * @Version V1。0  **/ public abstract class AbstractGoChess {     public abstract void show(GoChessPoint point); }

/**  * @ClassName WhiteGoChess  * @Description: 具體享元角色類:白棋  * @Author ford  * @Date 2021/4/29  * @Version V1。0  **/ public class WhiteGoChess extends AbstractGoChess {     @Override     public void show(GoChessPoint point) {         System。out。println(“白棋, ” + point);    } }

/**  * @ClassName BlackGoChess  * @Description: 具體享元角色類:黑棋  * @Author ford  * @Date 2021/4/29  * @Version V1。0  **/ public class BlackGoChess extends AbstractGoChess {      @Override     public void show(GoChessPoint point) {         System。out。println(“黑棋, ” + point);    } }

/**  * @ClassName GoChessPoint  * @Description: 非享元角色類(外部狀態,棋子座標)  * @Author ford  * @Date 2021/4/29  * @Version V1。0  **/ public class GoChessPoint {     // x 座標     private double x;     // y 座標     private double y;      public GoChessPoint(double x, double y) {         this。x = x;         this。y = y;    }      @Override     public String toString() {         return “棋子座標{” +                 “x=” + x +                 “, y=” + y +                 ‘}’;    } }

/**  * @ClassName GoChessFactory  * @Description: 享元工廠角色:圍棋工廠類  * @Author ford  * @Date 2021/4/29  * @Version V1。0  **/ public class GoChessFactory {     // 餓漢式模式例項化單例物件     private static GoChessFactory goc = new GoChessFactory();     // 存放白棋/黑棋物件     private Map goChessMap = new HashMap<>();      // 私有化預設構造方法     private GoChessFactory() {         goChessMap。put(“白棋”, new WhiteGoChess());         goChessMap。put(“黑棋”, new BlackGoChess());    }      // 獲取單例物件     public static GoChessFactory GetInstance() {         return goc;    }      /**      * 獲取棋子物件      *      * @param name      * @return      */     public AbstractGoChess getGoChess(String name) {         return goChessMap。get(name);    } }

享元模式客戶端測試

/**  * @ClassName GoClient  * @Description: 享元模式客戶端:圍棋客戶端測試類  * @Author ford  * @Date 2021/4/29  * @Version V1。0  **/ public class GoClient {     public static void main(String[] args) {         // 獲取白棋物件         AbstractGoChess white1 = GoChessFactory。GetInstance()。getGoChess(“白棋”);         AbstractGoChess white2 = GoChessFactory。GetInstance()。getGoChess(“白棋”);         // 獲取黑棋物件         AbstractGoChess black1 = GoChessFactory。GetInstance()。getGoChess(“黑棋”);         AbstractGoChess black2 = GoChessFactory。GetInstance()。getGoChess(“黑棋”);          // 展示白棋1         white1。show(new GoChessPoint(11。5, 20。8));         // 展示白棋2         white2。show(new GoChessPoint(11。5, 20。8));         System。out。println(“white1==white2: ” + (white1 == white2));         System。out。println(“===============================”);         // 展示黑棋1         black1。show(new GoChessPoint(21。5, 26。7));         // 展示黑棋2         black2。show(new GoChessPoint(16。1, 28。3));         System。out。println(“black1==black2: ” + (black1 == black2));     } }

白棋, 棋子座標{x=11。5, y=20。8} 白棋, 棋子座標{x=11。5, y=20。8} white1==white2: true =============================== 黑棋, 棋子座標{x=21。5, y=26。7} 黑棋, 棋子座標{x=16。1, y=28。3} black1==black2: true  Process finished with exit code 0

小結

本章分享了享元模式,主要介紹了享元模式的定義、角色、類圖,並以圍棋需求為例進行程式碼實現。

若本文使你受益,還請給予關注、點贊、轉發,歡迎拍磚!!!