【设计模式】享元模式 实现 ( 实现流程 | 抽象享元类 | 具体享元类 | 享元工厂 | 用户调用 | 代码模板 )
文章目錄
- I . 享元模式 實現流程
- II . 享元模式 抽象享元類
- III . 享元模式 具體享元類
- IV . 享元模式 享元工廠
- V . 享元模式 用戶調用
I . 享元模式 實現流程
1 . 定義抽象享元類 : 定義抽象類 , 內部狀態 , 外部狀態 , 抽象方法 ;
① 抽象類 : 該類是一個 抽象類 , 在 享元工廠類 和 用戶調用 中 , 涉及的對象類型就聲明為該 抽象類型 , 一般不直接使用具體的實現類 ;
② 定義內部狀態 : 內部狀態數據是多個 細粒度對象 ( 用戶實際使用的一萬個對象 ) 共享的信息 , 共享就是在對象池中的維護一個享元對象 ( 共享對象 ) , 當多個 細粒度對象 從 享元工廠類 中獲取該享元對象時 , 獲取的都是該享元對象 ( 共享對象 ) , 這些細粒度對象 ( 用戶使用的對象 ) 使用的內部狀態 ( 數據 ) 肯定都是一樣的 ; 定義時不用太關心該狀態 , 區分內部狀態與外部狀態即可 ;
③ 定義外部狀態 : 該狀態很重要 , 該信息作為從對象池中獲取對象的依據 ; 即外部狀態相等的兩個對象 , 說明對象是相同的 ;
④ 定義抽象行為 : 享元類實際的操作 , 此處是抽象方法 , 也是最終用戶調用該享元類調用的方法 ;
2 . 定義具體享元類 : 繼承抽象享元類 , 實現抽象享元類的抽象方法 ;
① 繼承 : 該類繼承 抽象的享元類 , 可以定義多個具體享元類 ;
② 使用 : 聲明享元類對象時 , 聲明抽象享元類類型 , 實際為該對象賦值時 , 需要賦值具體的享元類 ;
③ 對象池對象 : 享元工廠類中的對象池 , 可以存儲不同的具體享元類對象 , 但必須都是抽象享元類的子類對象 ;
3 . 定義享元工廠類 :
① 定義對象池 : 對象池一般是 Map 鍵值對類型 , 使用 抽象享元類對象的 外部狀態 數據作為鍵 , 值就是 享元類對象 ;
② 對象獲取機制 : 當用戶根據 外部狀態 獲取享元類對象時 , 先在對象池中查找是否存在該享元對象 , 如果存在直接返回該對象 , 如果不存在 , 那么創建該對象 , 將新創建的對象放入對象池中 , 并返回該享元對象 ;
4 . 用戶調用 : 用戶使用 享元工廠類 創建 抽象享元類 類型對象 , 并為其賦值一個 具體的享元類 對象 , 調用 抽象的方法 ;
II . 享元模式 抽象享元類
1 . 定義 抽象享元類 AbstractFlyweight :
① 定義內部狀態 : private String intrinsicState是內部狀態 , 也就是多個 細粒度對象 ( 用戶持有的多個對象 ) 共享的信息 , 這部分內容我們不關心 , 為其設置 Getter 和 Setter 方法即可 ;
② 定義外部狀態 : protected final String externalState , 外部狀態推薦使用 final 修飾 , 這是為了避免其在構造函數外的地方修改該值 , 外部狀態值只能在對象創建的時候賦值一次 , 其它任何時候都不允許修改該值 ;
③ 定義抽象行為 : abstract void action() , 這是享元類的具體邏輯 , 在具體享元角色中實現該類 ;
2 . 抽象享元類 代碼示例 :
package kim.hsl.design.flyweight;/*** 抽象的享元角色*/ public abstract class AbstractFlyweight {/*** 內部狀態*/private String intrinsicState;/*** 外部狀態* 注意使用 final 修飾只能 ① 馬上初始化 ② 在構造函數中初始化* 沒有其它的初始化途徑*/protected final String externalState;public AbstractFlyweight(String externalState) {this.externalState = externalState;}/*** 抽象的行為*/abstract void action();/*下面是訪問內部狀態的 Getter 和 Setter 方法*/public String getIntrinsicState() {return intrinsicState;}public void setIntrinsicState(String intrinsicState) {this.intrinsicState = intrinsicState;}/*** 獲取外部狀態的數據* 該數據用于 作為 對比兩個對象是否一致 的依據* @return*/public String getExternalState() {return externalState;} }III . 享元模式 具體享元類
1 . 定義具體享元類 ConcreteFlyweight :
① 繼承 : 該類繼承 AbstractFlyweight 抽象類 ;
② 重寫構造函數 : 抽象類實現類需要重寫有參構造函數 ;
③ 實現抽象方法 : 具體的享元類中需要實現 抽象享元類中的 抽象行為 ;
2 . 具體享元類 代碼示例 :
package kim.hsl.design.flyweight;/*** 具體的享元角色* 注意要實現 抽象方法 , 覆蓋其非默認的構造函數*/ public class ConcreteFlyweight extends AbstractFlyweight {public ConcreteFlyweight(String externalState) {super(externalState);}@Overridevoid action() {System.out.println("享元對象行為 , 外部狀態 : " + externalState);} }IV . 享元模式 享元工廠
1 . 定義 享元工廠類 :
① 對象池 : 享元工廠類 中維護一個靜態的 HashMap<String, AbstractFlyweight> 數據結構 , 這就是對象池在內存中的數據結構 , 鍵 String 數據就是 享元類的 外部狀態 , 用于作為 享元對象 的 身份標識 , 每個享元對象的該 外部狀態值 都不一樣 ;
② 從對象池中獲取對象 : 從 HashMap<String, AbstractFlyweight> OBJECT_POOL 對象池中獲取 AbstractFlyweight 抽象享元類 對象時 , 先檢查對象池中是否有該數據 , 如果使用 map.get() 獲取的 享元對象不為空 , 說明對象池中有該數據 , 直接返回即可 ; 如果 map.get() 獲取的 享元對象為空 , 說明對象池中沒有該對象 , 需要創建該對象 , 放入對象池 , 然后返回 ; 注意要使用 外部狀態傳入構造函數創建對象 ;
2 . 享元工廠類 代碼示例 :
package kim.hsl.design.flyweight;import java.util.HashMap;/*** 享元工廠* 維護對象池*/ public class FlyweightFactory {/*** 對象池* 使用對象時, 從對象池中查找* 如果找到直接取出* 如果沒有找到, 創建一個新對象, 放入對象池中, 然后返回該對象* 鍵 : 外部狀態 值 : 享元對象*/private static final HashMap<String, AbstractFlyweight> OBJECT_POOL = new HashMap<String, AbstractFlyweight>();public static AbstractFlyweight getObject(String externalState){//從對象池中獲取對象ConcreteFlyweight object = (ConcreteFlyweight) OBJECT_POOL.get(externalState);//如果對象池中沒有該對象if(object == null){object = new ConcreteFlyweight(externalState);OBJECT_POOL.put(externalState, object);System.out.println("創建新對象 外部狀態 值 : " + externalState + " , 并放入對象池");}else{System.out.println("獲取對象池中已有的對象 , 外部狀態 值 : " + externalState);}return object;} }V . 享元模式 用戶調用
1 . 用戶調用 :
① 用戶聲明對象類型 : 用戶聲明 AbstractFlyweight 抽象享元類的對象 , 從享元工廠類的對象池中獲取對象 ;
② 新建對象 : 如果對象池中沒有對象 , 會調用構造函數 , 創建該對象 , 并放入對象池中 , 再返回該對象 ;
② 復用對象 : 如果對象池中有該享元對象 , 那么直接從線程池中獲取該對象 , 并返回 ;
2 . 用戶調用 代碼示例 :
package kim.hsl.design.flyweight;public class Main {/*** 注意 : 享元對象使用時, 創建的是抽象的享元類* @param args*/public static void main(String[] args) {//外部狀態值為 "tom" , 對象池中沒有該對象, 創建后放入對象池, 然后從對象池中取出使用AbstractFlyweight tom = FlyweightFactory.getObject("tom");tom.action();//外部狀態值為 "tom" 的對象之前已經創建過, 直接從對象池中取出使用AbstractFlyweight tom2 = FlyweightFactory.getObject("tom");tom2.action();//外部狀態值為 "Jerry" , 對象池中沒有該對象, 創建后放入對象池, 然后從對象池中取出使用AbstractFlyweight jerry = FlyweightFactory.getObject("Jerry");jerry.action();} }總結
以上是生活随笔為你收集整理的【设计模式】享元模式 实现 ( 实现流程 | 抽象享元类 | 具体享元类 | 享元工厂 | 用户调用 | 代码模板 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【设计模式】享元模式 简介 ( 定义 |
- 下一篇: 【Java 集合】Java 集合的线程安