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