它看起来像是解决了我们没有失望的一个主要问题.不幸的是有一个缺点.接口发布后的任何更改都需要对该接口的任何消费者进行后续的重新编译.这对于所有发行周期都是一部分的项目来说是适用的,但是我们的一些项目有不同的发布时间表.
我已经研究了这一点,看起来通常的做法是引入一个继承自以前发布的界面的新界面,而不是修改原始界面.
type IOriginalInterface = interface ['{8B598EC1-AD92-4144-A1BE-9062C5EA0748}'] procedure DoSomething; end; INewInterface = interface(IOriginalInterface) ['{DD9D9DE0-0F87-4BC5-803C-74C8AB0F3E39}'] procedure DoSomethingElse; end;
这可以确保根据原始界面编译的旧版可执行文件继续工作.
我注意到RAD Studio打开的工具api,每当引入新的接口时,界面都会被重命名.因此,最新界面不会将最新界面赋予新名称,而是获取原始界面的名称,并重命名原始界面.
type IOldInterface = interface ['{8B598EC1-AD92-4144-A1BE-9062C5EA0748}'] procedure DoSomething; end; IOriginalInterface = interface(IOldInterface) ['{DD9D9DE0-0F87-4BC5-803C-74C8AB0F3E39}'] procedure DoSomethingElse; end;
这对于RAD Studio团队以及第三方扩展供应商来说显然效果很好.这样可以确保任何重新编译的客户端都将使用最新的界面,而无需任何代码更改.我认为这是因为这个名称是无关紧要的,而且在编译代码之后,所有这些都是接口定义,它是使用GUID来解决的.
说完这一切,这是我们现在面临的界面版本控制问题的一个很好的解决方案吗?还有其他问题需要注意吗?
解决方法
对于意图由插件和IDE扩展使用的接口,您对接口的版本化和命名方式是正确的.这个想法是现有的代码将引用一个特定的接口名称,因为所有现有的方法也存在于该接口上.由于旧代码根本无法引用任何新方法,因此可以将它们包含在新界面中.
但是,如果仔细观察,对于通过插件或IDE扩展实现的接口,您将看到相反的情况.新接口获得新名称,所有较旧的现有接口保持不变.这是因为,作为接口的实现者,您必须实现接口的所有方法.根据定义,现有的代码将不会实现新的方法.当IDE需要调用用户实现的方法时,它将始终通过查询引入该方法的接口的版本来进行该调用,这可能不是接口的最新版本.因此,应该将所有祖先接口列出为在实现类上实现.
总而言之,IDE的ToolsAPI的规则是,对于插件使用的接口,界面的最新版本总是获取未版本的名称.对于插件实现的接口,新的接口总是得到一个新的名字.