歡迎光臨
每天分享高質量文章

設計樣式之職責鏈樣式

職責鏈樣式簡介及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、如果編寫不註意,極有可能導致迴圈呼叫

 


    已同步到看一看
    贊(0)

    分享創造快樂