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

向接口添加新函数

  •  9
  • fletcher  · 技术社区  · 14 年前

    我需要为现有接口上的函数创建重载,而不影响当前实现或使用该接口的任何组件(理想情况下)。

    我想我有几个选择:

    简化 原始接口:

    public interface IServerComponent
    {
        bool Add(int a, int b);
    }
    

    我可以向接口添加新的重载函数,并强制实现接口的每个类实现新函数。

    public interface IServerComponent
    {
        bool Add(int a, int b);
        bool Add(int a, int b, int c);
    }
    

    或者我可以创建一个实现原始接口的新接口。那么其他使用原始的类就不需要更改,任何新的类都可以实现新的接口…

    public interface IServerComponent2 : IServerComponent
    {
        bool Add(int a, int b, int c);
    }
    

    这种情况下的最佳实践是什么?还有其他的选择吗?

    谢谢

    6 回复  |  直到 14 年前
        1
  •  11
  •   Stephen Cleary    14 年前

    如果新方法可以用旧方法表示,则可以使用扩展方法:

    // Original interface
    public interface IServerComponent 
    { 
      bool Add(int a, int b, int c); 
    } 
    
    // New overload
    public static class MyServerMethods
    {
      public static bool Add(this IServerComponent component, int a, int b)
      {
        return component.Add(a, b, 0);
      }
    }
    

    如果方法不能这样表达(即它们确实需要由组件本身实现),那么我建议定义一个新的接口。这种方法具有最大的向后兼容性。

        2
  •  4
  •   dtb    14 年前

    如果您的IServerComponent接口尚未发布,或者是一个仅由您自己的类实现的内部接口,并且新的接口成员对于实现该接口的所有现有类都是有意义的,请更改现有接口。

    否则,创建扩展IServerComponent的IServerComponent2接口。IIRC这是框架设计指南推荐的。可以在.NET框架中找到一个这样的示例,其形式为 X509Certificate2 班级。

    但是,如果新成员可以根据原始成员实现,则也可以使用 extension methods :

    public interface IServerComponent
    {
        bool Add(int a, int b);
    }
    
    public static class ServerComponentExtensions
    {
        public static bool Add(this IServerComponent isc, int a, int b, int c)
        {
            return isc.Add(a, b) && isc.Add(b, c) && isc.Add(c, a);
        }
    }
    
        3
  •  1
  •   Flory    14 年前

    我知道你的例子是人为的,但是我想给你一个与你所表达的不同的人为的答案,这样你就可以用不同的方式来思考它。不是让你的接口方法在具体的东西上操作,而是在抽象的东西上工作。

    例如

    public interface IAddableThings
    {
      int a;
      int b;
    }
    
    public interface IOtherAddableThings : IAddableThings
    {
      int a;
      int b;
    }
    
    public interface IServerComponent
    {
        bool Add(IAddableThings things);
    }
    

    如果这确实是一个加法,那么我认为这更有意义,但是如果它更像calculate(),那么您将希望将一些或所有方法操作向下移动到IAddableThings对象。

    public interface IAddableThings
    {
      int a;
      int b;
      bool CalculateMe();
    }
    
        4
  •  0
  •   Grzenio    14 年前

    它取决于上下文——如果有许多类实现了原始接口,或者如果发布了它,那么唯一可行的方法就是引入新的接口。另一方面,从长远来看,只有一个接口要干净得多,所以如果您能负担得起的话,我建议您重构现有的接口。

        5
  •  0
  •   mahju    14 年前

    如果您不需要或不想更改已经实现旧接口的类(现在或将来),您应该只创建第二个接口。然而,它感觉更像是一个黑客,可能会给您提供不太直观的代码。

    另外,根据我的经验,推迟重构从来不是一个好主意。因此,如果您怀疑稍后需要实现接口,那么您也可以修改现有的接口,让自己省去一些麻烦。这无疑是更清洁的方法。

        6
  •  0
  •   Afshar Mohebi    14 年前

    我认为维护单个接口更容易,但是第二种方法使用2个接口更好,因为不是每个类都需要实现 bool Add(int a, int b, int c);