快速學(xué)習(xí)C# 設(shè)計(jì)模式之職責(zé)鏈模式
職責(zé)鏈模式簡介及UML
職責(zé)鏈也叫責(zé)任鏈,他是一種行為型模式,它為請(qǐng)求創(chuàng)建了一個(gè)接收請(qǐng)求者對(duì)象的鏈,并將請(qǐng)求沿著這條鏈傳遞到目標(biāo)對(duì)象去處理。
該模式最簡單的實(shí)現(xiàn)方式就是運(yùn)用里氏替換原則,對(duì)每個(gè)職責(zé)所持有的對(duì)象進(jìn)行抽象,并使得每個(gè)職責(zé)對(duì)象都擁有共同的父類,通過對(duì)外提供出具有一般意義的接口。

范例
該范例,是我在對(duì)微服務(wù)中,服務(wù)發(fā)現(xiàn)的容錯(cuò)性進(jìn)行處理的一種處理方案,考慮到服務(wù)發(fā)現(xiàn)過程中,如果注冊(cè)中心宕機(jī),那么可以使用本地文件存放的臨時(shí)性信息,如果本地文件不存在,那么就直接用內(nèi)容中存放的信息。在整個(gè)流程中,我從注冊(cè)中心獲取服務(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é)鏈模式將請(qǐng)求的發(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ì)在一定程度上對(duì)系統(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é)鏈模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
判斷一個(gè)整數(shù)是否是2的N次冪實(shí)現(xiàn)方法
下面小編就為大家分享一篇判斷一個(gè)整數(shù)是否是2的N次冪實(shí)現(xiàn)方法,實(shí)例簡潔,具有很好的參考價(jià)值。希望對(duì)大家有所幫助2017-11-11
Unity多語言轉(zhuǎn)換工具的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Unity多語言轉(zhuǎn)換工具的實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06

