我有一个具有许多虚函数的类,允许您获取对接口(interface)的引用。使用我的 API 的客户端可以实现我的接口(interface),然后使用它们的实现来实现我的顶级接口(interface) 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?
最佳答案
我从你的问题中了解到:
如果我没理解错的话,你是在用或多或少的类和基本组件的集合来表达,你希望能够用最少的编码来交换组件。
方案一:动态组装
为什么不在构造时选择它们进行动态装配:
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”(那里的政策用模板实现的策略模式)。
关于c++ - 您将如何重构这种多态设计以使其在添加新实现时更加灵活?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39758894/