接口版本演化引发的思考一

    有一条基本的设计原则是“对接口编程”,什么意思呢?就是首先通过接口定义协定,也就是接口能够对外提供的功能描述,然后通过具体的类实现该接口。下面是个实现举例
 1class IA
 2{
 3public:
 4    virtual void OperationA() = 0;
 5}
;
 6class A1 : public IA
 7{
 8public:
 9    virtual void OperationA() {}
10}
;

    这样的实现扩展比较容易,可以通过新的实现类提供该接口服务的不同实现版本,比如:
1class A2 : public IA
2{
3public:
4    virtual void OperationA() {}
5}
;
    使用代码片段如下:
    IA* a1 = new A1();
    a1
->OperationA();
    delete a1;

    IA
* a2 = new A1();
    a2
->OperationA();
    delete a2;

    如果由于需求的变更导致接口IA必须提供新的服务,这个时候就有两种选择:一种是直接在接口IA中加入该服务,另一种是通过接口IA继承新的接口类型(比如IB),在IB中加入该服务。具体实现如下:
1class IA
2{
3public:
4    virtual void OperationA() = 0;
5    virtual void OperationB() = 0;
6}
;
1class IB : public IA
2{
3public:
4    virtual void OperationB() = 0;
5}
;

    这两种实现都能够完成任务,区别是前者的变更会导致所有依赖于该接口的具体实现类或者是接口都必须增加对该新服务的支持,这往往会产生链式反应。后者能够在保证原接口功能不便的情况下加入对新功能的支持。是个不错的选择。缺点是如果要使用新服务必须从接口IB继承
  怎样实现既使用IA接口提供的新功能又不改变依赖于IA代码呢?答案是使用提供缺省实现的虚函数,具体实现如下:
1class IA
2{
3public:
4    virtual void OperationA() = 0;
5    virtual void OperationB() {}
6}
;
    这样具体实现类型A如果不需要改变该新服务(OperationB)的默认实现,就不需要提供该服务的实现。

    纯虚函数的接口演化方案和提供默认实现的接口演化方案对应c#中的接口和抽象类之间的区别。
    有兴趣的朋友可以看看MSDN Library for Visual Studio 2005上对两者的使用描述。
    
   

posted on 2006-09-03 23:19  小峰  阅读(181)  评论(0)    收藏  举报

导航