2009-07-29 64 views
0

我正在開發一個計算組件配置的各種因素的項目。 配置由用戶在運行時設置/更改。我有一個組件基類,所有的配置項都是從它派生的。DataInterface的體系結構設計 - 刪除類型的開關

每個組件的信息都是在需要時從數據存儲中檢索的。 因此,存儲介質可以改變我寫了一個DataInterface類充當中介。

當前存儲介質是Access數據庫。 DataInterface類因此打開數據庫並創建查詢字符串以提取相關數據。查詢字符串對於每個組件都是不同的。

我遇到的問題是設計如何在組件類和DataInterface類之間調用GetData。我的解決方案演變如下:

1)DataInterface爲每個組件類型都有一個公共方法GetXXXXXData()。 (其中XXX是組件類型)。

Sensor sensor = new Sensor(); 
sensor.Data = DataInterface.GetSensorData(); 

2)DataInterface有一個公共方法GetData(componentType)並在組件類型中進行切換。

Sensor sensor = new Sensor(); 
sensor.Data = DataInterface.GetData(ComponentType.Sensor); 

3)抽象組件基類有虛方法GetData(),它由每個派生類過濾。 GetData()使用DataInterface類來提取數據。

Sensor sensor = new Sensor(); 
sensor.GetData(); 
//populates Data field internally. Could be called in constructor 

對於我來說,解決方案3似乎是最有效的做事方式。但是我仍然有這個問題,DataInterface仍然需要打開調用者的類型來決定使用哪個查詢字符串。

我可以將這些信息放入每個組件對象中,但是這會將組件耦合到所選擇的存儲介質。不好。另外,組件不應該關心數據的存儲方式。它應該調用它的GetData方法並返回數據。

希望這是有道理的。我正在尋找的是一種實現上述功能的方式,不依賴於使用開關類型。

我還在學習如何設計建築,所以任何關於改進的意見都歡迎。

TIA

回答

0

首先,我同意每個組件對象的想法,它的構造函數負責詢問其配置。事實上,也許這是推到基類的構造函數。我們以

DataInterface.GetData(getMyType()); 

一種呼叫。

然後,你的主要問題,我們如何實現GetData(類型)?

實際上,您希望從類型映射到查詢字符串,並且不希望在添加新組件時更改代碼。那麼如何提供一些數據驅動的方法。一個簡單的外部配置證明了映射。然後,只需要更改配置即可添加更多組件。

1

實際上,解決方案#3是最差的,因爲它給了Sensor類人爲責任。另外兩個解決方案更好,因爲它們將數據訪問責任封裝到不同的類中。

我會建議下面的接口和類。

interface IComponentDataReader 
{ 
    object GetData(); 
} 

abstract class AbstractComponent 
{ 
    private IComponentDataReader dataReader; 

    public AbstractComponent(IComponentDataReader dataReader) 
    { 
     this.dataReader = dataReader; 
    } 

    protected object GetData() 
    { 
     return dataReader.GetData(); 
    } 
} 

class Sensor : AbstractComponent 
{ 
    public Sensor(IComponentDataReader dataReader) 
     : base(dataReader) 
    { 
    } 

    public void DoSomethingThatRequiresData() 
    { 
     object data = GetData(); 

     // do something 
    } 
} 

class SensorDataReader : IComponentDataReader 
{ 
    public object GetData() 
    { 
     // read your data 

     return data; 
    } 
} 

class MyApplication 
{ 
    public static void Main(string[] args) 
    { 
     Sensor sensor = new Sensor(new SensorDataReader()); 
     sensor.DoSomethingThatRequiresData(); 
    } 
} 

我希望這是有道理的。基本上,對於良好的OOD,如果你可以讓你的課只做一件事(單一職責原則)並且只知道自己,你會沒事的。如果只知道自己,爲什麼有一個IComponentDataReader傳遞給SensorComponent?在這種情況下,請考慮將其提供給SensorComponent(依賴注入),而不是它的請求(這會在自己的職責之外尋找)。

+0

所以,如果我已經正確理解你的答案;如果我添加一個新組件,比如Resistor,那麼我還需要添加一個名爲ResistorDataReader的類? – Kildareflare 2009-07-29 10:05:51

0

如果我理解你的權利,你讓它有點太複雜了:

  1. 定義的iterface與getData()方法(和一些連接,斷開連接方法也許有些例外也將是一個好主意)。
  2. 派生一個單獨的類bassed像「AcdcessStorage」,「MySQLStorage」,「WhateverStroage」該接口上的每個數據提供商/不同的存儲類型...
  3. 現在您可以快速交換一個數據存儲實現另一個有不同連接方法/查詢字符串,並且您可以同時使用多個存儲區,並通過靜態接口方法遍歷它們,從而訪問所有存儲並將它們保存在列表中。

不需要任何開關。