職責鏈樣式簡介及UML
職責鏈也叫責任鏈,他是一種行為型樣式,它為請求建立了一個接收請求者物件的鏈,並將請求沿著這條鏈傳遞到標的物件去處理。
該樣式最簡單的實現方式就是運用里氏替換原則,對每個職責所持有的物件進行抽象,並使得每個職責物件都擁有共同的父類,透過對外提供出具有一般意義的介面。
範例
該範例,是我在對微服務中,服務發現的容錯性進行處理的一種處理方案,考慮到服務發現過程中,如果註冊中心宕機,那麼可以使用本地檔案存放的臨時性資訊,如果本地檔案不存在,那麼就直接用內容中存放的資訊。在整個流程中,我從註冊中心獲取服務資訊,然後寫入到檔案中,最終存放到記憶體。
處理者抽象類
internal abstract class ToleranceHandler { protected ToleranceHandler handler; public void SetToleranceHandler(ToleranceHandler handler) { this.handler = handler; } public abstract Taskstring, List>> HandlerRequestAsync(int request); }
服務中心處理
internal class ConsulHandler : ToleranceHandler { public override async Taskstring, List>> HandlerRequestAsync(int request) { if (request == 2) { var result = await this.GetRegisterServiceDictionary(); return result == null ? await this.handler.HandlerRequestAsync(1) : result; } else { return await this.handler.HandlerRequestAsync(request); } } }
檔案處理
internal class FileHandler:ToleranceHandler { private static readonly string fileName = "SubscribeService.json"; public override async Taskstring, List>> HandlerRequestAsync(int request) { if (request == 0) { StreamReader sr = File.OpenText(fileName); string result = await sr.ReadToEndAsync(); return result.FromJsonstring, List>>(); } else { return await this.handler.HandlerRequestAsync(request); } } }
記憶體處理
internal class InMemoryHandler : ToleranceHandler { public override async Taskstring, List>> HandlerRequestAsync(int request) { if (request == 1) { IMemoryCache memoryCache = new MemoryCache(Options.Create(new MemoryCacheOptions())); var result = memoryCache.Getstring, List>>("ServiceRegisterDiscovery:List"); return result == null ? await this.handler.HandlerRequestAsync(0) : result; } return await this.handler.HandlerRequestAsync(request); } }
客戶端呼叫
public async Task> GetService(string serviceName) { ToleranceHandler consulHandler = new ConsulHandler(); ToleranceHandler fileHandler = new FileHandler(); ToleranceHandler inMemoryHandler = new InMemoryHandler(); consulHandler.SetToleranceHandler(fileHandler); fileHandler.SetToleranceHandler(inMemoryHandler); Dictionary<string, List> serviceDic = await consulHandler.HandlerRequestAsync(2); return serviceDic[serviceName]; }
優缺點
優點:
1、職責鏈樣式將請求的傳送者與接收者剝離開來,實現了雙方的解耦,而解耦後的最佳效果就是,雙方關於自有功能的定製更加簡單,修改產生的影響也大大減輕。
2、傳送方呼叫時,無需知道鏈的結構,只需要設定好鏈路結構即可。
3、可以利用鏈路的組合特性,實現職責鏈組合的配置化,當然需要額外編寫控制程式碼
缺點
1、可能會導致類檔案過多,當然也有人說職責鏈會在一定程度上對系統的效能造成不利影響,不過這條我認為可以忽略,因為從系統維護的角度來說,這點犧牲是允許的。
2、如果編寫不註意,極有可能導致迴圈呼叫
朋友會在“發現-看一看”看到你“在看”的內容