簡體   English   中英

定義采用不同參數的接口方法

[英]Define an interface method that takes different parameters

我的應用程序使用連接到PC的測量儀器。 我希望能夠使用來自不同供應商的類似儀器。

所以我定義了一個接口:

interface IMeasurementInterface
    {
        void Initialize();
        void Close();
    }

到現在為止還挺好。 在測量之前,我需要設置儀器,這意味着不同儀器的參數非常不同。 所以我想定義一個方法,它接受可以有不同結構的參數:

interface IMeasurementInterface
{
    void Initialize();
    void Close();
    void Setup(object Parameters);
}

然后我會將對象投射到我需要的任何東西上。 這是要走的路嗎?

你可能最好想出一個抽象的“參數”類,它由每個不同的儀器參數擴展...例如然后使用泛型來確保將正確的參數傳遞給正確的類......

public interface IMeasurement<PARAMTYPE> where PARAMTYPE : Parameters
{
    void Init();
    void Close();
    void Setup(PARAMTYPE p);
}

public abstract class Parameters
{

}

然后針對每個特定設備,

public class DeviceOne : IMeasurement<ParametersForDeviceOne>
{
    public void Init() { }
    public void Close() { }
    public void Setup(ParametersForDeviceOne p) { }
}

public class ParametersForDeviceOne : Parameters
{

}

對我而言,聽起來像工廠模式可能是有用的,特別是如果你要對你的應用進行單元測試。

如果您打算處理多種設備類型,那么使用Name vlaue對進行通信的控制器+設備接口分離將是一個很好的解決方案

解耦

使用名稱值對可以將代碼分離到設備+控制器+應用程序代碼結構中

示例代碼

class DeviceInterface
    {
    void Initialize(IController & Controller);
    void Close();
    bool ChangeParameter(const string & Name, const string & Value); 
    bool GetParam(string & Name, string &Value );
    }

創建時,每個設備實現都應使用可接受其命令的控制器標識創​​建,並將其轉換為實際的設備命令

interface IController
   {
   Initialize(DeviceSpecific & Params);
   Close();
   bool ChangeParameter(string & Name, string & Value);
   bool ChangeParams(string & Name[], string &Value []);
   }

您的用戶代碼看起來像這樣

IController     objController = new MeasurementDevice(MeasureParram);

DeviceInterface MeasureDevice = new DeviceInterface(objController);

string Value;

MeasureDevice.GetParam("Temperature", Value);

if (ConvertStringToInt(Value) > 80)
     {
     MeasureDevice.ChangeParameter("Shutdown", "True");
     RaiseAlert();
     }

DeviceInterface類應該做的就是將命令傳遞給控制器​​。 控制器應該負責設備通信。

界面分離的優點

保護更改

這種解耦將允許您將應用程序代碼與控制器隔離。 設備更改不會影響您的用戶代碼

申請代碼的可維護性

此外,用戶代碼始終是干凈的,您只需要使用應用程序邏輯。 但是,如果您使用特定於控制器的多種類型的參數結構定義了多個接口/創建的模板或泛型,那么您的代碼中將包含許多依賴於設備的垃圾,這可能會損害可讀性並在您的設備/其參數發生變化時產生維護問題。

實施輕松

您還可以將不同的控制器實現分配到自己的項目中。 此外,您的應用程序還可以使用XML文件等以更動態的方式配置命令和響應,這些文件可以與控制器類一起發布,從而使您的整個應用程序本質上變得更加動態。

現實生活

來自該領域領導者的最新生產控制器項目之一以相同的方式工作。 但他們使用LON進行設備通信。

LON?

控制器(想想空調/鍋爐/風扇等)網絡中使用的LON協議使用這個概念與各種設備通信

因此,您需要擁有的是一個可以與您的設備通信的接口,然后使用LON將名稱值對發送給它。 他使用標准協議還允許您與測量儀器以外的其他設備通信。 如果您的設備使用LON,則可以使用LON的開源實現。

如果您的設備不支持LON,那么您可能必須設計用戶代碼仍在名稱值對上工作的東西,而相反的接口將您的名稱值對轉換為對應的cotroller struct +,並以設備的方式與個性化設備通信理解。

希望這很有用。

這取決於你如何獲得參數。 如果它們存儲在某個數據庫表或配置文件中,並且它只是需要設置的值,那么傳入字典可能會這樣做(盡管你確實失去了類型安全性)。 如果您的設置過程稍微復雜一點,那么我會考慮進一步抽象設置過程並執行雙重調度(將強制轉換操作推送到新的安裝類)。 像這樣

public interface IMeasurementInterface
{
  void Initialize();
  void Close();
  void Setup( IConfigurer config );
}

public interface IConfigurer
{
  void ApplyTo( object obj );
}

public abstract ConfigurerBase<T> : IConfigurer where T : IMeasurementInterface
{
  protected abstract void ApplyTo( T item );

  void IConfigurator.ApplyTo(object obj )
  {
    var item = obj as T;
    if( item == null )
      throw new InvalidOperationException("Configurer can't be applied to this type");
    ApplyTo(item);
  }
}

這樣你就不會弄亂你的Measurement類層次結構(或者沒有提供任何實現,並假設所有實現都會按照你想要的方式執行)。 這也意味着您可以通過傳入假(或模擬)測量設備來測試您的安裝代碼。

如果設置過程需要操作私有或受保護的數據,那么您可以使IConfigurer的具體實現駐留在其相應的Measurement類中。

我需要為我的軟件使用這個,因為我需要支持許多不同類型的金屬切割機運動控制器。

您的界面具有您需要的基礎知識。 您需要記住的是,您不需要傳入參數列表。 您指出每種類型的設備可能具有非常不同類型的設置。

我這樣做的方式如下

interface IMeasurementInterface
{
    void Initialize();
    void Close();
    void Setup();
    void Read (FileReader as <whatever read file object you are using>)
    void Store (FileReader as <whatever read file object you are using>)
    string Name();
}

安裝程序調用在IMeasurementDevice程序集中創建的對話框。 該對話框在程序集外部不可見。

現在我知道一些面向對象或MVC純粹主義者可能會反對這一點。 但是我覺得隱藏特定Measurement類的內部結構的概念超過了對MVC架構的嚴格遵守。

我的一般理念是trival對話框在同一個程序集中實現,前提是它對程序集是私有的,並由我設置的標准接口上實現的對象調用。 再次出現這種情況的原因是我發現隱藏內部結構比嘗試在頂級程序集中實現所有對話框更有價值。

通過指定Read方法和Store方法,您無需公開內部設置參數以進行保存。 您只需要傳遞用於保存設置參數的任何類型的文件存儲對象。

最后,如同另一張海報所述,您需要在裝配中設置包含所有測量設備的工廠類。 在設置過程中,您需要實例化此類並檢索支持的測量設備列表。

我這樣做的方法是我的工廠類檢索一個運動控制器列表。 此列表是存儲所有安裝類的主類的一部分。 當我讀取我的安裝文件時,我得到了實際使用的控制器。 我從列表中檢索這些類,並將它們放在切割過程中實際使用的另一個列表中。

我這樣做的原因是當用戶設置運動控制器時,他需要能夠從所有可用控件的列表中選擇,以便告訴軟件他有哪一個。 我發現保持可用控制器列表更具響應性。

這可能會奏效。 另一種選擇是在字典中傳遞參數。

暫無
暫無

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

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