1. 程式人生 > 程式設計 >快速學習C# 設計模式之職責鏈模式

快速學習C# 設計模式之職責鏈模式

職責鏈模式簡介及UML

職責鏈也叫責任鏈,他是一種行為型模式,它為請求建立了一個接收請求者物件的鏈,並將請求沿著這條鏈傳遞到目標物件去處理。

該模式最簡單的實現方式就是運用里氏替換原則,對每個職責所持有的物件進行抽象,並使得每個職責物件都擁有共同的父類,通過對外提供出具有一般意義的介面。

快速學習C# 設計模式之職責鏈模式

範例

該範例,是我在對微服務中,服務發現的容錯性進行處理的一種處理方案,考慮到服務發現過程中,如果註冊中心宕機,那麼可以使用本地檔案存放的臨時性資訊,如果本地檔案不存在,那麼就直接用內容中存放的資訊。在整個流程中,我從註冊中心獲取服務資訊,然後寫入到檔案中,最終存放到記憶體。

處理者抽象類

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);
}

服務中心處理

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);
    }
  }
}

記憶體處理

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);
  }
}

客戶端呼叫

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];
}

客戶端呼叫優缺點

優點:

1、職責鏈模式將請求的傳送者與接收者剝離開來,實現了雙方的解耦,而解耦後的最佳效果就是,雙方關於自有功能的定製更加簡單,修改產生的影響也大大減輕。

2、傳送方呼叫時,無需知道鏈的結構,只需要設定好鏈路結構即可。

3、可以利用鏈路的組合特性,實現職責鏈組合的配置化,當然需要額外編寫控制程式碼

缺點

1、可能會導致類檔案過多,當然也有人說職責鏈會在一定程度上對系統的效能造成不利影響,不過這條我認為可以忽略,因為從系統維護的角度來說,這點犧牲是允許的。

2、如果編寫不注意,極有可能導致迴圈呼叫

以上就是快速學習C# 設計模式之職責鏈模式的詳細內容,更多關於c# 職責鏈模式的資料請關注我們其它相關文章!