代码之家  ›  专栏  ›  技术社区  ›  Kepboy

使用相同的接口定义但提供不同的行为可以吗?

  •  0
  • Kepboy  · 技术社区  · 17 年前

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

    我将尝试用一些代码来澄清。我有下面定义的接口。

    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>();
    }
    

    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。然而,StationTranslations将成功,即不同的行为。这可以吗,我认为接口是用来定义行为和结构的?

    基思。

    1 回复  |  直到 17 年前
        1
  •  2
  •   dsimcha    17 年前

    这很好。这样想:确定任何继承关系是否“ok”的关键是 Liskov substitution principle.

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