1. 初始
应用A和应用B均用到了库libX.a中的类class A:
由于需求的变化,应用B需要库libM.a的能力,以便和服务M交互。为了复用和简化,通过类A间接提供,应用B不用修改代码,只需要重新编译即可获得新的能力,其它用到类A的应用也是如此。
这个时候会产生一个问题,会导致应用A的Makefile也需要指定库libZ.a,否则编译时会报库libZ.a中的符号找不到错误。
需要一种方法来解除应用A对库libZ.a的依赖。
2. 方法一:使用宏限定库libZ.a
这个方法要求类A全头文件方式,不能有.cpp文件,因为需要分别在编译应用A和应用B时选择性开启对库libZ.a的依赖。
这个方法虽然解决了问题,但是应用B得修改,需要增加打开宏的代码,其它有类似需求的应用均需要如此操作,涉及修改面比较大。
3. 方法二:使用NULL模式
这种方法扩展性更好,新增其它的依赖也能应付,已有或不需要新特性的完全不需要修改,编译不受影响,不会被迫依赖libM.a。
class IX { public: virtual ~IX() {} virtual void method1() = 0; virtual void method2() = 0; };
class CNullX: public IX { private: virtual void method1() { /* 什么都不做 */ } virtual void method2() { /* 什么都不做 */ } };
class CMX: public IX { private: virtual void method1() { // 调用libM.a和Server M交互 }
virtual void method2() { // 调用libM.a和Server M交互 } };
// 原类A class A { public: // 新增默认参数x,并保持和原兼容 A(IX* x=NULL) { _x = (x != NULL)? x: new CNullX; }
virtual ~A() { delete _x; }
public: void method1() { _x->method1(); }
void method2() { _x->method2(); }
private: IX* _x; };
// 对于应用A,不用修改任何代码,而且编译时不需要依赖libM.a // 对于应用B,需要微修改,并编译时指定库libM.a和Server void ApplicatonB::f() { CMX* x = new CMX; A a(x); a.method1(); } |