放鬆1秒鐘
什麼是享元模式
運用共享技術來有效地支援大量細粒度物件的複用。它透過共享已經存在的物件來最大程度減少需要建立的物件數量,避免大量相似物件的開銷,從而提高系統資源的利用率。
享元模式,也叫作蠅量模式,屬於結構型設計模式。
享元模式類圖
享元模式角色
抽象享元角色(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
享元模式客戶端測試
/** * @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
小結
本章分享了享元模式,主要介紹了享元模式的定義、角色、類圖,並以圍棋需求為例進行程式碼實現。
若本文使你受益,還請給予關注、點贊、轉發,歡迎拍磚!!!