簡述
將各個功能拆分后分別封裝(各功能解耦),需要時可自由組合(包括執行順序)
話不多說,看個優化案例吧,
優化案例
最初版
以下是模擬客戶端想服務端發送請求的業務流程,
客戶端呼叫代碼如下,
// 客戶端
public class Client {
public static void main(String[] args) {
Map<String, String> request = new HashMap<>();
request.put("username", "admin");
request.put("password", "admin");
service(request);
}
public static void service(Map<String, String> request) {
String username = request.get("username");
String password = request.get("password");
if (!"admin".equals(username) || !"admin".equals(password)) {
throw new RuntimeException("用戶名或密碼不正確!");
}
System.out.println("用戶認證通過,");
System.out.println("正在處理請求的業務,");
}
}
如果根據新的需求,需要在用戶認證通過到處理請求的業務之間增加一個快取用戶資訊至Session的處理該怎么辦,傳統的寫法肯定是直接在上述代碼的第14行后加入一條快取用戶資訊的處理,但這樣下去,以后每次增加這部分的需求是都無一例外的需要修改客戶端的代碼,并且實際上客戶端發送請求的方法肯定不止一處,如果有一個新業務是需要在每個請求的方法中都添加呢,那又怎么辦?現在上面的代碼只是模擬,所以只需要加一行列印輸出即可,真實的邏輯可比這復雜得多,到時候的代碼量也是現在的好幾倍,豈不麻煩死了?
為了解決這個問題,我們可以使用責任鏈模式,
修改版v1
增加一組類,使用責任鏈模式,如下,
// 責任鏈的頂級介面
// 定義責任鏈的核心功能
public interface Chain {
// 指定下一個處理
void setNext(Chain next);
// 處理當前請求
void handler(Map<String, String> request);
}
// 責任鏈的抽象父類
// 定義所有責任鏈物件共通的屬性和方法
public abstract class AbstractChain implements Chain {
// 持有下一個處理
private Chain next;
public Chain getNext() {
return next;
}
@Override
public void setNext(Chain next) {
this.next = next;
}
}
// 用戶認證模塊
public class AuthChain extends AbstractChain {
@Override
public void handler(Map<String, String> request) {
String username = request.get("username");
String password = request.get("password");
if (!"admin".equals(username) || !"admin".equals(password)) {
throw new RuntimeException("用戶名或密碼不正確!");
}
System.out.println("用戶認證通過,");
Chain next = this.getNext();
if (next == null) {
throw new RuntimeException("處理中斷!");
}
next.handler(request);
}
}
// Session快取模塊
public class SessionChain extends AbstractChain {
@Override
public void handler(Map<String, String> request) {
System.out.println("快取用戶資訊至Session,");
Chain next = this.getNext();
if (next == null) {
throw new RuntimeException("處理中斷!");
}
next.handler(request);
}
}
// 業務處理模塊
public class ProcessChain extends AbstractChain {
@Override
public void handler(Map<String, String> request) {
System.out.println("正在處理請求的業務,");
}
}
修改后,客戶端代碼的呼叫如下,
public class Client {
public static void main(String[] args) {
Map<String, String> request = new HashMap<>();
request.put("username", "admin");
request.put("password", "admin");
service(request);
}
public static void service(Map<String, String> request) {
Chain auth = new AuthChain();
Chain session = new SessionChain();
Chain process = new ProcessChain();
auth.setNext(session);
session.setNext(process);
auth.handler(request);
}
}
熟悉資料結構的同學肯定一眼就看出了責任鏈模式的本質:鏈表,將一個冗長的業務處理流程拆分成各個模塊,使用時根據業務流程以鏈表的形式將其串聯,不僅提升了各個模塊代碼的復用性,而且還能是的各個模塊自由組合,極大的提升了開發效率,
總結
優點
- 可以自由指定各個模塊的執行順序,
- 各個模塊遵循單一職責使得各個模塊間解耦,
- 新增業務流程時只需要增加新的模塊即可,遵循開閉原則,提升了系統的可維護性,
缺點
- 當業務流程過長時,組成的業務鏈也會非常的長,涉及到的物件過多可能會影響系統的性能,
- 雖然各個模塊可以自由組合,但是組合的作業實際上都放在了客戶端,這無疑提升了客戶端的代碼復雜度,
適用場景
- 業務流程類的功能都可以使用責任鏈模式,
- 公司或政府部門各級對于檔案的審批,需要各級各部門蓋章簽字,并且其中一環未通過就得打回重新審核,
本文來自博客園,作者:spoonb,轉載請注明原文鏈接:https://www.cnblogs.com/spoonb/p/16748754.html
個人主頁:blogcafe.cn 比博客園更新速度更快,歡迎大家的光顧
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/530542.html
標籤:其他
