我有一个具有许多虚函数的类,允许您获取对接口的引用。使用我的API的客户端可以实现我的接口,然后使用他们的实现实现我的顶级接口IMyInterface。
然后我的代码会对其多态IMyInterface实现起作用。
这里有一些示例代码(不是真正的代码,但你明白了):
class MyImplementation : public IMyInterface
{
public:
virtual Interface1& get1()
{
return impl1
}
virtual Interface2& get2()
{
return impl2;
}
// etc...
public:
Impl1 impl1;
Impl2 impl2;
// etc...
};
我认为这个设计看起来很不错,但有一天我想改变其中一个实现,但只有一个。在那种情况下,我必须重写整个类并复制大量代码。
实际上有6个Impl对象,所以我必须重写一个具有完全相同的5个Impl对象的类,但有一个不同。
另一个问题是人们依赖这种API设计,所以我需要保留它的基础知识。
有没有办法修改设计以使其更灵活,同时仍然维护此API?
答案 0 :(得分:1)
我从您的问题中理解:
如果我理解正确的话,你会使用或多或少的类和基本组件的汇编,并且你希望能够以最少的编码交换组件。
备选方案1:动态汇编
为什么不在施工中选择它们进行动态装配:
class MyBase : public IMyInterface
{
public:
Interface1& get1() { return *pimpl1; }
Interface2& get2() { return *pimpl2; }
//...
Interfacen& getn() { return *pimpln; }
protected:
MyBase (unique_ptr<Interface1> p1,
unique_ptr<Interface2> p2,
/*...*/
unique_ptr<Interfacen> pn) : // constructor assembles parts
pimpl1(move(p1)),pimpl2(move(p2)),/*...*/pimpln(move(pn)) {}
private:
unique_ptr<Interface1> pimpl1; // implemented with unique ptr for greater safety
unique_ptr<Interface2> pimpl2;
//...
unique_ptr<Interfacen> pimpln;
};
使用这样的逻辑,你的派生类看起来像:
class MyImplementationX : public MyBase {
public:
MyImplementationX() : MyBase(make_unique<Impl1>(), make_unique<Impl2>(), /*...*/ make_unique<Impln>()) {}
};
class MyImplementationY : public MyBase {
public:
MyImplementationX() : MyBase(make_unique<Impl1>(), make_unique<Impl2b>(), /*...*/ make_unique<Impln>()) {}
};
备选方案2:编译时程序集
您可以使用模板删除运行时程序集,附加分配和智能指针:
template <class I1, class I2, /*...*/ class IN,
class M1, class M2, /*...*/ class M3>
class MyBase {
public:
I1& get1() { return m1; }
I2& get2() { return m2; }
...
private:
M1 m1;
M2 m2;
...
};
顺便说一句,有一本关于这种设计的优秀书籍:A.Alexandrescu撰写的“ Modern C ++ design ”,其中作者宣传了“policy based design”(政策)存在用模板实现的策略模式)。