目錄
一 裝飾模式案例說明
1.1 說明
1.2 代碼
1.2.1?定義數據服務接口
1.2.2 定義基礎數據庫服務實現
1.2.3??日志裝飾器
1.2.4?緩存裝飾器
1.2.5 主程序調用
1.3 裝飾模式的特點
一 裝飾模式案例說明
1.1 說明
本案例是:數據查詢增加緩存,使用到了裝飾模式
1.裝飾器鏈構建:
new CachingDecorator(new LoggingDecorator(new DatabaseService()))
2.順序是:緩存裝飾器包裹日志裝飾器,日志裝飾器包裹基礎數據庫服務
3.流程
-
第一次查詢?(
user_123
):-
進入緩存裝飾器:緩存中沒有,繼續向下
-
進入日志裝飾器:記錄開始日志
-
進入數據庫服務:執行實際查詢
-
返回日志裝飾器:記錄完成日志
-
返回緩存裝飾器:緩存結果
-
最終返回結果給主程序
-
-
第二次查詢?(
user_123
):-
緩存裝飾器發現緩存中存在,直接返回
-
不會觸發日志和數據庫查詢
-
1.2 代碼
1.2.1?定義數據服務接口
public interface DataService {String fetchData(String userId);
}
1.2.2 定義基礎數據庫服務實現
public class DatabaseService implements DataService {@Overridepublic String fetchData(String userId) {// Simulate fetching data from a databasereturn "db中數據00: " + userId;}
}
1.2.3??日志裝飾器
public class LoggingDecorator implements DataService {private final DataService wrappedService;public LoggingDecorator(DataService wrappedService) {this.wrappedService = wrappedService;}@Overridepublic String fetchData(String userId) {System.out.println("查詢db中內容: " + userId);String result = wrappedService.fetchData(userId);System.out.println("logging查詢db: " + result);return result;}
}
1.2.4?緩存裝飾器
public class CachingDecorator implements DataService {private final DataService wrappedService;private final Map<String, String> cache = new HashMap<>();public CachingDecorator(DataService wrappedService) {this.wrappedService = wrappedService;}@Overridepublic String fetchData(String userId) {if (cache.containsKey(userId)) {System.out.println("查詢緩存獲取內容: " + userId);return cache.get(userId);} else {String result = wrappedService.fetchData(userId);cache.put(userId, result);return result;}}
}
1.2.5 主程序調用
public class TestZs {public static void main(String[] args) {DataService service = new CachingDecorator(new LoggingDecorator(new DatabaseService()));String result = service.fetchData("user_123");System.out.println("main方法顯示結果:"+result);System.out.println("====================");// Fetching again to demonstrate cachingresult = service.fetchData("user_123");System.out.println(result);}
}
結果:
1.3 裝飾模式的特點
關鍵點說明
裝飾器順序很重要:
如果把緩存裝飾器放在最內層,日志每次都會記錄
當前順序確保了緩存命中時不會產生日志
線程安全:
使用 ConcurrentHashMap 保證緩存操作的線程安全
擴展性:
可以輕松添加其他裝飾器(如性能監控、權限檢查等)
透明性:
客戶端代碼不需要知道具體實現細節
這種設計模式非常適合需要動態添加功能的場景,同時保持了代碼的整潔和可維護性