簡體   English   中英

是否有設計模式可以幫助我存儲對象“功能”?

[英]Is there a design pattern that can help me store object "capabilities"?

我正在開發一個 C# 程序,該程序允許用戶通過 TCP telnet 樣式連接(根據各種設備制造商的命令集)與各種 AV 設備進行交互並進行配置,例如接收器和切換器。 我使用命令模式來封裝命令。 應用程序一次只能與一台設備交互,因此當它連接時,它會枚舉設備並創建一個 DeviceVersion 對象。 該對象存儲所有設備共有的某些屬性。 它還需要維護每個設備的功能列表。 例如,某些設備沒有音量控制。 其他人可以,但不能更改輸入設備。 我討厭在每個 DeviceVersion 對象中存儲一長串布爾值的想法。 我想我應該有一個類似於 CapabilityContract 對象的東西,它封裝了一個字典,比如可以將功能名稱映射到布爾值的字典。 至少我可以通過文本配置文件或其他方法放入 ContractFactory 或可以動態生成這些功能對象的東西。

但是,在解析命令輸出時,在某些情況下,允許的功能可能會改變解析響應的方式。 例如,可以在輸出上分離音頻和視頻的 AV 開關可能有一個 GetInput 命令,該命令返回一個有序對,如(音頻輸入、視頻輸入),但是,在音頻和視頻始終鏈接的設備上,它可能只返回(輸入)。 命令解析器接口實現維護對 DeviceVersion 的引用,因此它可以查找功能,但這會導致相當多的 if 語句或 switch 語句。 我想為每個 DeviceVersion 類型生成不同的解析器實現,但這會導致大量重復代碼。 是否有一些我遺漏的設計模式可以為我簡化這個問題並避免大量維護布爾值或大量重復代碼?

目前尚不清楚 DeviceVersion 類的目的是什么,也許 DeviceInfo 描述得更好。 我的建議是使用 IDeviceCapability 集合,其中每個項目代表一種功能,例如 IPlayable。 通過這種方式,您可以附加/分離、獲取信息、啟用/禁用以及使用所有功能執行其他操作,但對於所有特定功能只有一種實現。 盡管您無論如何都可以覆蓋它們。

另一個好處是您可以分別測試和模擬 DeviceInfo 類的每個功能。 DeviceCapability 中的更改不會影響 DeviceInfo 和所有 DeviceCapability 實現。

如果我要解決這個問題,我會使用Factory Pattern ,也在MSDN 上,在那里我定義了一個基本接口(沒有實現)或抽象類(包含一些實現),然后是一個工廠來檢索這些對象。

通過這種方式,您的系統有一個通用的實現來與這些設備進行通信,並且您不會復制代碼,因為您只是繼承基類來為您可能與之交互的每個設備創建實現。 我建議你讓你的 DeviceVersion 對象更通用一點,然后把它變成基類。 您可以將您的命令模式實現包裝到工廠模式中,這應該可以幫助您實現目標。

不久前,我使用這種模式來實現一個 C# 應用程序,該應用程序允許您使用四種不同的 SDK 在四種不同類型的 DVR 之間切換。

這是一個快速而骯臟的例子:

設備類型枚舉:

public enum DeviceType {
  Receiver,
  Switcher
  // etc
}

基類:

public interface DeviceVersion {
  // What type is this?
  DeviceType DeviceType { get; }

  // Common Properties and Methods, etc here
  #region Function Availability Properties

  bool CanFastForward { get; }
  bool CanPlay { get; }
  bool CanStop { get; }
  bool Can... { get; }
  ...

  #endregion

  #region Methods

  bool Connect(string ipAddress, string user, string password);
  void Disconnect();
  void Play();
  void Stop();
  ...

  #endregion
}

切換器類:

public class Switcher : DeviceVersion {
  // Override the virtual
  public DeviceType DeviceType { get { return DeviceType.Switcher; } }

  public bool CanPlay
  {
      get { return true; }
  }
  ...
}

工廠等級:

public class DeviceFactory {
  // This is the factory method
  public static DeviceVersion GetDevice(DeviceType type) {
    switch (type) {
      case DeviceType.Switcher:
        return new Switcher();
      case DeviceType.Receiver:
        ...
      default:
        ...
    }
  }
}

然后在您連接到不同設備時的主要方法中:

...
var currentDeviceType = DeviceTypes.Switcher;
...
var device = DeviceFactory.GetDevice(currentDeviceType);
if (device.Connect("1.2.3.4", "user", "pass")) {
  if (device.CanPlay)
    device.Play();
  ...
}
...

至於契約和功能,您可以在基類中實現一個字典或類似的東西來保存這些項目,因為基類中的所有內容都由從它繼承的類繼承。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM