代码之家  ›  专栏  ›  技术社区  ›  Manish Basantani

如何重构一个胖接口?

  •  4
  • Manish Basantani  · 技术社区  · 14 年前

    假设我有以下一组接口……

     public interface IStart
            {
                void M1();
                bool IsWorking { get; }
            }
    
        public interface IStartStop : IStart
            {
                void M2();
                       event EventHandler DoM1;
                event EventHandler DoM2;
            }
        public interface IPreferencesReader : IStartStop, IDisposable
            {
                string CustomColumnDefinition       {get;}
                    bool UsePricelevelDetection  {get;}
                void InitializePreferences();
            }
    

    现在,如果我想实现IPreferencesReader,我的类如下所示。这是一个fat接口的例子,其中 必须提供我可能不需要的所有场景中的方法的实现。

    public class PreferencesReaderBase : IPreferencesReader
        {
            public void M1()
            {
                throw new NotImplementedException();
            }
    
            public bool IsWorking
            {
                get { throw new NotImplementedException(); }
            }
    
            public void M2()
            {
                throw new NotImplementedException();
            }
    
            public event EventHandler DoM1;
            public event EventHandler DoM2;
    
            public void Dispose()
            {
                throw new NotImplementedException();
            }
    
            public string CustomColumnDefinition
            {
                get { throw new NotImplementedException(); }
            }
    
            public bool UsePricelevelDetection
            {
                get { throw new NotImplementedException(); }
            }
    
            public void InitializePreferences()
            {
                DoSomeInitialization();
            }
        }
    

    我可以为这个场景应用任何模式来重构它吗?

    编辑:我不能没有这个层次结构,因为在不能删除任何接口。

    谢谢你的兴趣。

    3 回复  |  直到 14 年前
        1
  •  1
  •   Carl Manaster    14 年前

    使用“适配器”模式-而不是 one 维基百科识别,所以也许我的术语是非标准的,但就像Java的 MouseAdapter :

    的抽象适配器类 接收鼠标事件。中的方法 这个类是空的。这个班 作为创建的便利而存在 侦听器对象。

    扩展此类以创建 MouseEvent Listener并重写 有关事件的方法。 (如果您实现mouseListener 接口,您必须定义 其中的方法。这个抽象类 为所有方法定义空方法,因此 只能定义方法 对于你关心的事件。)

    只需编写一个抽象类,其中包含所有必需接口的空实现;对其进行子类化并重写与您的需求相关的方法。

    完整的胖接口仍然存在;它仍然由您的类实现(通过继承)-但是您的类的代码将只包含重要的内容。

        2
  •  2
  •   Adam Houldsworth    14 年前

    您不一定需要提供工作实现。在您的示例中,您的ipreferencesReader似乎不需要istartstop,因此您可以简单地删除其中的包含内容吗?

    如果要从实现类型中隐藏接口方法(即,在PreferencesReaderBase对象中看不到它),可以显式实现接口:

    void IStart.Start() { }
    

    然后,您只能通过将您的PreferencesReaderBase引用强制转换为IStart引用来调用这些接口方法。

        3
  •  2
  •   Mongus Pong    14 年前

    我想你需要研究一下为什么你不能打破你的界面继承权。您说继承权是必要的,但是有些类不需要实现所有的方法。这意味着不需要继承权!

    如果IPreferencesReader不需要实现M1方法,那么它实际上不是IStart。它订立的合同是无效的。

    记住,类可以继承多个接口。假设您打破了继承继承关系,那么如果preferrencesreaderbase确实是IStop,但不是IStart,则可以将其声明为:

    public class PreferencesReaderBase : IPreferencesReader, IStop
    

    如果出于任何原因您真的不能拆分这个接口,您可以考虑拆分实现类。

    class Start
    {
      M1() 
      {
    
      }
    }
    
    class Stop
    {
      M2()
      { 
    
      }
    }
    
    public class PreferencesReaderBase : IPreferencesReader
    {
      private Start start = new Start();
      private Stop stop = new Stop()
      public void M1()
      {
          this.start.M1();
      }
    
    
      public void M2()
      {
          this.stop.M2();
      }
    }
    

    这样至少可以保持主要功能类的整洁。每个班都做一件事,所以 Single Responsibility Principle 保持。

    Fat接口类是一个框架类,在开发迭代过程中可以基本上保持原样。