【設計模式】享元模式 實現 ( 實現流程 | 抽象享元類 | 具體享元類 | 享元工廠 | 用戶調用 | 代碼模板 )
文章目錄
I . 享元模式 實現流程
II . 享元模式 抽象享元類
III . 享元模式 具體享元類
IV . 享元模式 享元工廠
V . 享元模式 用戶調用
1 . 定義抽象享元類 :
定義抽象類 , 內部狀態 , 外部狀態 , 抽象方法 ;
① 抽象類 :
該類是一個 抽象類 ,
在 享元工廠類 和 用戶調用 中 , 涉及的對象類型就聲明為該 抽象類型 , 一般不直接使用具體的實現類 ;
② 定義內部狀態 :
內部狀態數據是多個 細粒度對象 ( 用戶實際使用的一萬個對象 ) 共享的信息 ,
共享就是在對象池中的維護一個享元對象 ( 共享對象 ) ,
當多個 細粒度對象 從 享元工廠類 中獲取該享元對象時 , 獲取的都是該享元對象 ( 共享對象 ) ,
這些細粒度對象 ( 用戶使用的對象 ) 使用的內部狀態 ( 數據 ) 肯定都是一樣的 ;
定義時不用太關心該狀態 , 區分內部狀態與外部狀態即可 ;
③ 定義外部狀態 :
該狀態很重要 , 該信息作為從對象池中獲取對象的依據 ;
即外部狀態相等的兩個對象 , 說明對象是相同的 ;
④ 定義抽象行為 :
享元類實際的操作 , 此處是抽象方法 , 也是最終用戶調用該享元類調用的方法 ;
2 . 定義具體享元類 :
繼承抽象享元類 , 實現抽象享元類的抽象方法 ;
① 繼承 :
該類繼承 抽象的享元類 , 可以定義多個具體享元類 ;
② 使用 :
聲明享元類對象時 , 聲明抽象享元類類型 , 實際為該對象賦值時 , 需要賦值具體的享元類 ;
③ 對象池對象 :
享元工廠類中的對象池 , 可以存儲不同的具體享元類對象 , 但必須都是抽象享元類的子類對象 ;
3 . 定義享元工廠類 :
① 定義對象池 :
對象池一般是 Map 鍵值對類型 , 使用 抽象享元類對象的 外部狀態 數據作為鍵 , 值就是 享元類對象 ;
② 對象獲取機制 :
當用戶根據 外部狀態 獲取享元類對象時 , 先在對象池中查找是否存在該享元對象 , 如果存在直接返回該對象 ,
如果不存在 , 那么創建該對象 , 將新創建的對象放入對象池中 , 并返回該享元對象 ;
4 . 用戶調用 :
用戶使用 享元工廠類 創建 抽象享元類 類型對象 , 并為其賦值一個 具體的享元類 對象 , 調用 抽象的方法 ;
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; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
1 . 定義具體享元類 ConcreteFlyweight :
① 繼承 :
該類繼承 AbstractFlyweight 抽象類 ;
② 重寫構造函數 :
抽象類實現類需要重寫有參構造函數 ;
③ 實現抽象方法 :
具體的享元類中需要實現 抽象享元類中的 抽象行為 ;
2 . 具體享元類 代碼示例 :
package kim.hsl.design.flyweight; /** * 具體的享元角色 * 注意要實現 抽象方法 , 覆蓋其非默認的構造函數 */ public class ConcreteFlyweight extends AbstractFlyweight { public ConcreteFlyweight(String externalState) { super(externalState); } @Override void action() { System.out.println("享元對象行為 , 外部狀態 : " + externalState); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1 . 定義 享元工廠類 :
① 對象池 :
享元工廠類 中維護一個靜態的 HashMap
鍵 String 數據就是 享元類的 外部狀態 , 用于作為 享元對象 的 身份標識 , 每個享元對象的該 外部狀態值 都不一樣 ;
② 從對象池中獲取對象 :
從 HashMap
先檢查對象池中是否有該數據 , 如果使用 map.get() 獲取的 享元對象不為空 , 說明對象池中有該數據 , 直接返回即可 ;
如果 map.get() 獲取的 享元對象為空 , 說明對象池中沒有該對象 , 需要創建該對象 , 放入對象池 , 然后返回 ; 注意要使用 外部狀態傳入構造函數創建對象 ;
2 . 享元工廠類 代碼示例 :
package kim.hsl.design.flyweight; import java.util.HashMap; /** * 享元工廠 * 維護對象池 */ public class FlyweightFactory { /** * 對象池 * 使用對象時, 從對象池中查找 * 如果找到直接取出 * 如果沒有找到, 創建一個新對象, 放入對象池中, 然后返回該對象 * 鍵 : 外部狀態 值 : 享元對象 */ private static final HashMap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
數據結構
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。