请教:基于接口编程的一些疑问。
基于接口的编程是一种被广泛推广的方法,类似COM之类的组件都是这种方法的产物。它使用纯虚接口进行交互,杜绝了实现继承。这种强限制有一些好处,也导致了一些困难。
好处是,纯虚接口可以避免库与库之间的连接,例如我的dll都可以通过LoadLibrary的方式加载,也不用link在一起。这为插件设计提供了方便。
缺点是,具体的对象无法在栈上分配,无法实现继承将导致一些设计比较困难。
例如,考虑一个基于接口编程实现的GUI库,会发现实现这个库的扩展变得很困难:
class IWidget{};
class IButton : public IWidget{};
class ILable : public IWidget{};
class Button : public IButton{}
class Lable : public ILable{};
实现Button和Lable的代码会有很多都是相同的,一般来说这部分公共的代码都应该放到Widget的类里面去。但由于禁止了实现继承,这一步是做不到的。
另外一种办法是将公共的代码放到另外一个接口类里面,比如叫IWidgetImplHelper, 然后Button跟Lable持有一个WidgetImplHelper的实例,再将接口的调用转发到这个辅助类上面去,不过这样函数转发的代码也非常非常的多。
还可以使用WTL的办法,将公共实现写到模板里面:
template<typename C, typename I>
class WidgetTemplate : public I
{...};
class Lable : public WidgetTemplate<Lable, ILable>{...};
但是这样将导致将很多公共的代码都放到头文件中,编译效率将会非常低下,而且任意的代码修改将会导致很大的工程重新编译,纯虚接口带来的很多好处将不复存在。
那么在这个GUI库的设计上,该如何来满足开闭原则呢?库的使用者必须很方便的扩展这个库,而不需要改动到这个库的代码,甚至不用改动到这个库的dll。作为纯虚接口的库,只需要一些头文件,然后LoadLibrary这个库就能使用。该如何才能达人这点?
请教大家有什么好的建议么?