2009-03-02 77 views
0

我的问题的总结是“我有2个共享一个通用接口的类,但是这两个类在属性方面有不同的行为。一个接口抛出一个异常,如果参数值无效,另一个接口将其内部状态更新为处理无效的值,两个类是否可以共享相同的接口,或者应该定义两个接口,以向开发人员指出两者具有不同的行为?“可以使用相同的接口定义但提供不同的行为吗?

我会尝试用一些代码来澄清。我有界面定义如下。

 
public interface IStationDictionary 
{ 
    bool this[string stationId] { get; set; } 
} 

和一个实现接口的类,该类用于设置数字IO板上的输出端口。

 
public class DigitalStationAdapter : IStationDictionary 
{ 
    public bool this[string stationId] 
    { 
     get { return ports[stationId].Value; } 
     set { ports[stationId].Value = value; } 
    } 

    public void AddDigitalStation(string stationId, DigitalIoPort port) 
    { 
     ports.Add(stationId, port); 
    } 

    private IDictionary<string, DigitalIoPort> ports = new Dictionary<string, DigitalIoPort>(); 
} 

我也有记录哪些站有改变,因此这些改变可以propegated到数字IO值的类。

 
public class StationTransitions : IStationDictionary 
{ 
    public bool this[string stationId] 
    { 
     get 
     { 
      bool result = false; 

      if(changes.ContainsKey(stationId)) 
       result = changes[stationId]; 

      return result; 
     } 
     set 
     { 
      if(!changes.ContainsKey(stationId)) 
       changes.Add(stationId, value); 
      else 
       changes[stationId] = value; 
     } 
    } 

    public IDictionary GetChanges() 
    { 
     IDictionary<string, bool> result = changes; 

     changes = new Dictionary<string, bool> 

     return result; 
    } 

    private IDictionary<string, bool> changes = new Dictionary<string, bool>(); 
} 

所以,虽然这两个类实现相同的接口,如果你试图用的stationID访问索引不在字典DigitalStationAdapter将抛出一个KeyNotFoundException。而StationTransitions将会成功,即不同的行为。这没关系,我认为接口用于定义行为和结构?基思。

回答

2

这很好。这样考虑:确定任何继承关系是否“OK”的关键是Liskov substitution principle.这要求期望基类的代码应该能够在不知道它的情况下使用派生类。这意味着一个方法的先决条件不能在派生类中加强,但可以被削弱。接口只是基类的特例。

在你的情况下,接口的隐式前提条件是输入在你定义时是有效的。所有期望基类的代码应该假设这个前提条件,并避免传递无效数据或准备处理异常。在更新其内部状态来处理无效输入的具体类中,你正在弱化一个先决条件。就Liskov替代原则而言,这是可以接受的。另一方面,如果你想让自动处理无效输入的类抛出一个基类,并使抛出后裔的类失效,这将会很糟糕,因为代码期望基类类不能像派生类一样使用派生类。它必须知道派生类才能处理可能的异常。

相关问题