聲明:以下都是博主淺薄的經驗之談,歡迎大家學習交流
- 博主是參考這個視頻進行學習總結的:
- 設計模式學習視頻(點擊我)
- 提取碼 : 29oc
使用場景
- 我們在做系統設計的時候,一個非常重要的工作就是把大系統進行逐一的分解在分解。譬如用戶管理模塊、支付模塊,但是每一個模塊的某些業務功能都是通用。如在執行業務方法之前需進行這個操作:記錄業務方法的操作日誌;統計業務方法的執行時間;業務方法開始前開啓事務,方法結束之後提交事務,方法異常回滾事務。
- 於是就會產生如下類似的僞代碼
public void PayService{
public Response execute()
{
logger.debug("....");//記錄日誌
RecordTimeUtiles.startTime();//記錄業務方法執行時間
//執行業務方法的的代碼...
//......
//......
RecordTimeUtiles.endTime();
}
}
雖然這樣的代碼實現了功能,但是可想而知後續增加更多的業務功能方法,也都是需要重複以上的代碼。
此時可以應用模板方法設計模式來解決以上大部分代碼重複的問題。
- AbstractService.java
public abstract class AbstractService{
public void execute(){
logger.debug("....");//記錄日誌
RecordTimeUtiles.startTime();//記錄業務方法執行時間
//執行業務方法的的代碼...
//......
payServiceExecute();
//......
RecordTimeUtiles.endTime();
}
public abstract Response payServiceExecute();
}
- PayService.java
public class PayService extends AbstractService{
public Response payServiceExecute(){
//執行業務方法的的代碼...
//......
//......
}
}
- 此時父類AbstractService.java 已經將原先的記錄日誌、方法執行時間等重複性的代碼都寫好了,而子類PayService.java只需要通過實現父類的抽象方法【payServiceExecute】去實現自己需要的業務功能代碼即可!
調用的方式很簡單如下:
AbstractService as = new PayService();
as.execute();
- 缺點:這樣的方式最大的缺陷就是父類定義了一切,子類要毫無保留的去服從。什麼執行順序啥的,都不是子類所能控制的,假如某個子類不要統計方法的時間只要記錄日誌,此時這樣的設計方法就無能爲力了。
裝飾模式
如果利用裝飾模式,針對上面問題將會帶來更大的靈活性,且看!
Service.java
public interface Service{
Response execute();
}
- LogDecorator.java
public class LogDecorator implements Service{
private Service service;
public LogDecorator (Service service){
this.service = service;
}
public Response execute(){
logger.debug("....");//記錄日誌
this.service.execute();
}
}
- RecordTimeDecorator.java
public class RecordTimeDecorator implements Service{
private Service service;
public RecordTimeDecorator(Service service){
this.service = service;
}
public Response execute(){
RecordTimeUtiles.startTime();//記錄業務方法執行時間
this.service.execute();
RecordTimeUtiles.endTime();
}
}
- PayService.java
public class PayService implements Service{
public Response execute(){
//執行業務方法的的代碼...
//......
}
}
- 調用方式
//場景一:只需要記錄日誌
Service service = new LogDecorator(new PayService());
service.execute();
//場景二:只需要記錄業務方法執行的時間
Service service = new RecordTimeDecorator(new PayService());
service.execute();
//場景三:需要記錄日誌;記錄業務方法執行的時間
Service service = new RecordTimeDecorator(new LogDecorator(new PayService()));
service.execute();
- 是不是很靈活,我們要什麼就包裝什麼。而且還可能指定包裝的順序從而實現代碼執行的順序。
聲明:以上都是博主淺薄的經驗之談,歡迎大家學習交流
- 博主是參考這個視頻進行學習總結的,如閱讀不懂可參看本視頻哦!
- 設計模式學習視頻(點擊我)
- 提取碼 : ivtk