快速學(xué)習(xí)C# 設(shè)計(jì)模式之職責(zé)鏈模式
職責(zé)鏈模式簡介及UML
職責(zé)鏈也叫責(zé)任鏈,他是一種行為型模式,它為請求創(chuàng)建了一個(gè)接收請求者對象的鏈,并將請求沿著這條鏈傳遞到目標(biāo)對象去處理。
該模式最簡單的實(shí)現(xiàn)方式就是運(yùn)用里氏替換原則,對每個(gè)職責(zé)所持有的對象進(jìn)行抽象,并使得每個(gè)職責(zé)對象都擁有共同的父類,通過對外提供出具有一般意義的接口。
范例
該范例,是我在對微服務(wù)中,服務(wù)發(fā)現(xiàn)的容錯(cuò)性進(jìn)行處理的一種處理方案,考慮到服務(wù)發(fā)現(xiàn)過程中,如果注冊中心宕機(jī),那么可以使用本地文件存放的臨時(shí)性信息,如果本地文件不存在,那么就直接用內(nèi)容中存放的信息。在整個(gè)流程中,我從注冊中心獲取服務(wù)信息,然后寫入到文件中,最終存放到內(nèi)存。
處理者抽象類
internal abstract class ToleranceHandler { protected ToleranceHandler handler; public void SetToleranceHandler(ToleranceHandler handler) { this.handler = handler; } public abstract Task<Dictionary<string, List<Service>>> HandlerRequestAsync(int request); }
服務(wù)中心處理
internal class ConsulHandler : ToleranceHandler { public override async Task<Dictionary<string, List<Service>>> 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 Task<Dictionary<string, List<Service>>> HandlerRequestAsync(int request) { if (request == 0) { StreamReader sr = File.OpenText(fileName); string result = await sr.ReadToEndAsync(); return result.FromJson<Dictionary<string, List<Service>>>(); } else { return await this.handler.HandlerRequestAsync(request); } } }
內(nèi)存處理
internal class InMemoryHandler : ToleranceHandler { public override async Task<Dictionary<string, List<Service>>> HandlerRequestAsync(int request) { if (request == 1) { IMemoryCache memoryCache = new MemoryCache(Options.Create(new MemoryCacheOptions())); var result = memoryCache.Get<Dictionary<string, List<Service>>>("ServiceRegisterDiscovery:List"); return result == null ? await this.handler.HandlerRequestAsync(0) : result; } return await this.handler.HandlerRequestAsync(request); } }
客戶端調(diào)用
public async Task<List<Service>> GetService(string serviceName) { ToleranceHandler consulHandler = new ConsulHandler(); ToleranceHandler fileHandler = new FileHandler(); ToleranceHandler inMemoryHandler = new InMemoryHandler(); consulHandler.SetToleranceHandler(fileHandler); fileHandler.SetToleranceHandler(inMemoryHandler); Dictionary<string, List<Service>> serviceDic = await consulHandler.HandlerRequestAsync(2); return serviceDic[serviceName]; }
客戶端調(diào)用優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
1、職責(zé)鏈模式將請求的發(fā)送者與接收者剝離開來,實(shí)現(xiàn)了雙方的解耦,而解耦后的最佳效果就是,雙方關(guān)于自有功能的定制更加簡單,修改產(chǎn)生的影響也大大減輕。
2、發(fā)送方調(diào)用時(shí),無需知道鏈的結(jié)構(gòu),只需要設(shè)置好鏈路結(jié)構(gòu)即可。
3、可以利用鏈路的組合特性,實(shí)現(xiàn)職責(zé)鏈組合的配置化,當(dāng)然需要額外編寫控制代碼
缺點(diǎn)
1、可能會(huì)導(dǎo)致類文件過多,當(dāng)然也有人說職責(zé)鏈會(huì)在一定程度上對系統(tǒng)的性能造成不利影響,不過這條我認(rèn)為可以忽略,因?yàn)閺南到y(tǒng)維護(hù)的角度來說,這點(diǎn)犧牲是允許的。
2、如果編寫不注意,極有可能導(dǎo)致循環(huán)調(diào)用
以上就是快速學(xué)習(xí)C# 設(shè)計(jì)模式之職責(zé)鏈模式的詳細(xì)內(nèi)容,更多關(guān)于c# 職責(zé)鏈模式的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
判斷一個(gè)整數(shù)是否是2的N次冪實(shí)現(xiàn)方法
下面小編就為大家分享一篇判斷一個(gè)整數(shù)是否是2的N次冪實(shí)現(xiàn)方法,實(shí)例簡潔,具有很好的參考價(jià)值。希望對大家有所幫助2017-11-11Unity多語言轉(zhuǎn)換工具的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Unity多語言轉(zhuǎn)換工具的實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06