【问题标题】:Is it ok to use the same interface definition but provide different behaviour?可以使用相同的接口定义但提供不同的行为吗?
【发布时间】:2009-03-02 23:21:32
【问题描述】:

我的问题的摘要是“我有 2 个类共享一个公共接口,但是这两个类在其属性方面具有不同的行为。如果参数值无效,一个接口会引发异常,另一个会更新其内部状态来处理无效值。两个类可以共享同一个接口还是应该定义两个接口以向开发人员表明两者具有不同的行为?"

我会尝试用一些代码来澄清。我在下面定义了接口。

公共接口 IStationDictionary { bool this[string stationId] { get;放; } }

还有一个实现接口的类,这个类用来设置数字IO板上的输出端口。

公共类 DigitalStationAdapter : IStationDictionary { public bool this[string stationId] { 获取{返回端口[stationId].Value; } 设置 { 端口 [stationId].Value = 值; } } 公共无效 AddDigitalStation(字符串 stationId,DigitalIoPort 端口) { ports.Add(stationId, 端口); } 私有 IDictionary 端口 = new Dictionary(); }

我还有一个类可以记录哪些站点的值发生了更改,以便可以将这些更改传播到数字 IO。

公共类 StationTransitions : IStationDictionary { public bool this[string stationId] { 得到 { 布尔结果=假; 如果(更改。包含密钥(stationId)) 结果=更改[stationId]; 返回结果; } 放 { if(!changes.ContainsKey(stationId)) 更改。添加(stationId,值); 别的 更改[stationId] = 值; } } 公共 IDictionary GetChanges() { IDictionary 结果 = 变化; 更改 = 新字典 返回结果; } private IDictionary changes = new Dictionary(); }

因此,虽然两个类都实现了相同的接口,但如果您尝试使用不在字典中的 stationId 访问索引器,DigitalStationAdapter 将抛出 KeyNotFoundException。而 StationTransitions 将成功,即不同的行为。可以吗,我以为接口是用来定义行为和结构的?

基思。

【问题讨论】:

    标签: c# oop


    【解决方案1】:

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

    在您的情况下,接口的隐含前提条件是输入在您定义时是有效的。所有期望基类的代码都应该假设这个前提条件并避免传递无效数据或准备处理异常。在更新其内部状态以处理无效输入的具体类中,您正在削弱先决条件。就 Liskov 替换原则而言,这是可以接受的。

    另一方面,如果你要创建一个自动处理无效输入的类而不抛出一个基类,并创建一个抛出后代的类,这会很糟糕,因为代码需要基类不能像使用基类一样使用派生类。它必须知道派生类才能处理可能的异常。

    【讨论】:

      猜你喜欢
      • 2019-10-26
      • 2023-02-22
      • 1970-01-01
      • 1970-01-01
      • 2014-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多