假设您有一个界面IFoo
:
public interface IFoo {
void Bar(string s);
int Quux(object o);
}
在API的第2版中,您需要Glarg
向该接口添加方法。在不破坏现有API用户和保持向后兼容性的情况下,该如何做?这主要是针对.NET,但也可以应用于其他框架和语言。
假设您有一个界面IFoo
:
public interface IFoo {
void Bar(string s);
int Quux(object o);
}
在API的第2版中,您需要Glarg
向该接口添加方法。在不破坏现有API用户和保持向后兼容性的情况下,该如何做?这主要是针对.NET,但也可以应用于其他框架和语言。
Answers:
在API的第2版中,您需要
Glarg
向该接口添加方法。
为什么?
定义用于API的接口具有两个完全不同的角色:
现在,对于给定版本的API,相同的接口可以同时充当两者。不过,在将来的版本中,这可以解耦。
您想“返回更多”,即从您的API中抽象“更丰富”的对象。在这里,您有两种选择:
定义一个新接口,如果可能的话,可以从上一个接口派生。如果无法进行这种派生,请创建单独的方法来查询新接口的实例或使用composition:
interface MyNewInterface extends MyOldInterface {
FancyNewInterface getFancyShit();
}
向您的API添加一个或多个新方法的方式应该不会对现有API产生任何副作用。最重要的是,继续使用旧API的人(好像新API不存在)应该不受其影响。使用旧的API也不会对新的API 产生意外的副作用。
如果API中的任何现有方法都被新方法取代,请不要立即将其删除。将它们标记为已弃用,并提供有关应使用什么的解释。这向您的代码用户发出警告,即将来的版本可能不再支持它,而不是在没有警告的情况下破坏他们的代码。
如果新旧API不兼容并且无法一起使用而没有不希望的副作用,请将它们分开并说明如果要采用新API,则必须完全淘汰旧API。这是不太理想的,因为总会有人尝试同时使用两者,而在无法使用时会感到沮丧。
由于您是专门询问.NET的,因此您可能需要阅读有关.NET中弃用的文章,该文章链接到ObsoleteAttribute
(在以下示例中使用):
using System;
public sealed class App {
static void Main() {
// The line below causes the compiler to issue a warning:
// 'App.SomeDeprecatedMethod()' is obsolete: 'Do not call this method.'
SomeDeprecatedMethod();
}
// The method below is marked with the ObsoleteAttribute.
// Any code that attempts to call this method will get a warning.
[Obsolete("Do not call this method.")]
private static void SomeDeprecatedMethod() { }
}
公共接口更改涉及损坏。常见的策略是仅在主要版本上并且在冻结期之后执行这些操作(因此不会一时兴起)。如果您将添加的内容添加到新的界面中(您的实现可以在同一个类中提供这两者),则可以在不破坏客户的情况下逃脱现实。那不是理想的,如果继续这样做,您将一团糟。
但是,通过其他种类的修改(删除方法,更改签名),您将陷入困境。