1. 程式人生 > >11.java設計模式之享元模式

11.java設計模式之享元模式

#### 基本需求: * 小型的外包專案,給客戶A做一個產品展示網站,客戶A的朋友感覺效果不錯,也希望做這樣的產品展示網站,但是要求都有些不同 * 每個客戶要求釋出的方式不一樣,A要求以新聞的方式釋出,B要求以部落格的方式釋出,C要求以公眾號的方式釋出,並且多個釋出人可能選擇用同一種方式釋出 #### 傳統方案: * 直接複製A客戶的網站,在其上按照B的要求修改,定製化,給每個網站都租用一個空間 * 需要的網站結構相似度很高,而且都不是高訪問量網站,如果分成多個虛擬空間來處理,相當於一個相同網站的例項物件很多,造成伺服器的資源浪費 * 解決思路:整合到一個網站中,共享其相關的程式碼和資料,對於硬碟、記憶體、CPU、資料庫空間等伺服器資源都可以達成共享,減少伺服器資源 #### 基本介紹: * 享元模式(Flyweight)也叫'蠅量模式',主要用於減少建立物件的數量,以減少記憶體佔用和提高效能。這種型別的設計模式屬於結構型模式,它提供了減少物件數量從而改善應用所需的物件結構的方式。享元模式嘗試重用現有的同類物件,如果未找到匹配的物件,則建立新物件,有匹配的物件,則直接使用 * 運用共享技術有效地支援大量細粒度的物件,主要解決:在有大量物件時,有可能會造成記憶體溢位,我們把其中共同的部分抽象出來,如果有相同的業務請求,直接返回在記憶體中已有的物件,避免重新建立 * 常用於系統底層開發,解決系統的效能問題。像資料庫連線池,裡面都是建立好的連線物件,在這些連線物件中有我們需要的則直接拿來用,避免重新建立,如果沒有我們需要的,則建立一個 * 享元模式能夠解決重複物件的記憶體浪費的問題,當系統中有大量相似物件,需要緩衝池時。不需總是建立新物件,可以從緩衝池裡拿。這樣可以降低系統記憶體,同時提高效率 * 享元模式經典的應用場景就是池技術了,String 常量池、資料庫連線池、緩衝池等等都是享元模式的應用,享元模式是池技術的重要實現方式 * UML類圖(原理) * ![](https://img2020.cnblogs.com/blog/2093590/202011/2093590-20201119192540671-128836225.png) * 說明 * FlyWeight 是抽象的享元角色, 他是產品的抽象類, 同時定義出物件的外部狀態和內部狀態的介面或實現 * 享元模式提出了兩個要求:細粒度和共享物件。這裡就涉及到內部狀態和外部狀態了,即將物件的資訊分為兩個部分:內部狀態和外部狀態 * 內部狀態指物件共享出來的資訊, 儲存在享元物件內部且不會隨環境的改變而改變 * 外部狀態指物件得以依賴的一個標記,是 隨環境改變而改變的、不可共享的狀態 * 例如:下五子棋,圍棋等,使用的棋子就可以用享元模式定義,棋子的顏色就是內部狀態(兩種顏色不會改變),棋子在棋盤的位置隨選手的落子而決定就是外部狀態; * 可在棋子類 建立兩個屬性 一個顏色,一個位置,落子時每次在工廠獲取的都是同一個物件,只不過位置屬性的值不同而已,達到了這兩個棋子物件的複用 * ConcreteFlyWeight 是具體的享元角色,是具體的產品類,實現抽象角色定義相關業務 * UnSharedConcreteFlyWeight 是不可共享的角色,一般不會出現在享元工廠(一般也不會出現) * FlyWeightFactory 享元工廠類,內部構建一個池容器(集合),同時提供從池中獲取物件方法 * UML類圖(案例) * ![](https://img2020.cnblogs.com/blog/2093590/202011/2093590-20201119192550645-128055333.png) * 說明 * WebSite有不同的釋出狀態,用type表示,也就是其內部狀態,ConcreteWebSite為其實現類,具體的享元角色 * User為外部狀態,不同的User可以用相同的方式去釋出WebSite * WebSiteFactory為工廠類,用於維護WebSite池 * 程式碼實現 * >```java >public abstract class WebSite { > > // 享元抽象類 > > // 此屬性為內部狀態,釋出的形式只有幾種,新聞,部落格,公眾號 > protected String type; > > public WebSite(String type) { > this.type = type; > } > > // 使用User類作為外部狀態,不同的User可以釋出同一形式的網站(實際使用的是同一WebSite物件)達到了物件的複用 > public abstract void use(User user); > >} > >// 具體的享元類 >class ConcreteWebSite extends WebSite{ > > // 具體的享元產品 > > public ConcreteWebSite(String type) { > super(type); > } > > @Override > public void use(User user) { > System.out.println(user.getName() + "用" + this.type + "形式釋出了網站"); > } > >} >``` > > * >```java >@Data >@AllArgsConstructor >public class User { > > // WebSite的外部狀態 > private String name; > >} >``` > > * >```java >public class WebSiteFactory { > > // 享元工廠類,內部維護享元產品池 > > pri