2009-07-29 92 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. 现在您可以快速交换一个数据存储实现另一个有不同连接方法/查询字符串,并且您可以同时使用多个存储区,并通过静态接口方法遍历它们,从而访问所有存储并将它们保存在列表中。

不需要任何开关。