C++ 在添加新的实现时,您将如何重构此多态设计,以使其更加灵活?
我有一个类,它有许多虚拟函数,允许您获取对接口的引用。使用我的API的客户端可以实现我的接口,然后使用它们的实现实现我的顶级接口IMyInterface 然后,我的代码作用于它们的多态IMyInterface实现 下面是一些示例代码(不是真正的代码,但您知道了): 我觉得这个设计看起来很不错,但有一天我想改变其中一个实现,但只有一个。在这种情况下,我必须重写整个类并复制大量代码 实际上有6个Impl对象,所以我必须重写一个类,这个类有5个完全相同的Impl对象,但有一个不同的Impl对象 另一个问题是人们依赖这个API设计,所以我需要保留它的基础知识C++ 在添加新的实现时,您将如何重构此多态设计,以使其更加灵活?,c++,oop,inheritance,polymorphism,C++,Oop,Inheritance,Polymorphism,我有一个类,它有许多虚拟函数,允许您获取对接口的引用。使用我的API的客户端可以实现我的接口,然后使用它们的实现实现我的顶级接口IMyInterface 然后,我的代码作用于它们的多态IMyInterface实现 下面是一些示例代码(不是真正的代码,但您知道了): 我觉得这个设计看起来很不错,但有一天我想改变其中一个实现,但只有一个。在这种情况下,我必须重写整个类并复制大量代码 实际上有6个Impl对象,所以我必须重写一个类,这个类有5个完全相同的Impl对象,但有一个不同的Impl对象 另一个
是否有一种方法可以修改设计,使其更灵活,同时仍保持此API 我从你的问题中了解到了什么: 如果我理解正确,您使用的是或多或少的类和基本组件的组装,并且您希望能够用最少的代码交换组件 备选方案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 MyBase:public IMyInterface
{
公众:
Interface1&get1(){return*pimpl1;}
Interface2&get2(){return*pimpl2;}
//...
interfaceen&getn(){return*pimplot;}
受保护的:
MyBase(唯一的\u ptr p1,
唯一的_ptrp2,
/*...*/
唯一:\u ptr pn)://构造函数组装部件
pimpl1(移动(p1)),pimpl2(移动(p2)),/*…*/PIMPPLN(移动(pn)){}
私人:
unique_ptr pimpl1;//使用unique ptr实现更高的安全性
独特的ptr pimpl2;
//...
唯一的ptr项目;
};
使用这种逻辑,您的派生类将如下所示:
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>()) {}
};
类MyImplementationX:公共MyBase{
公众:
MyImplementationX():MyBase(make_unique(),make_unique(),/*…*/make_unique()){}
};
类MyImplementationY:公共MyBase{
公众:
MyImplementationX():MyBase(make_unique(),make_unique(),/*…*/make_unique()){}
};
备选方案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;
...
};
模板
类MyBase{
公众:
I1&get1(){return m1;}
I2&get2(){return m2;}
...
私人:
M1;
M2;
...
};
顺便说一句,有一本关于A. Alexandrescu的“现代C++设计”的优秀书籍,其中作者提倡一个“(有一个用模板实现的策略模式的策略)。p> 也许更适合CodeReview或程序员?例如,为什么您必须“重写整个类并复制大量代码”,从而改变“Impl2”的某些内容?@J。。。代码审查需要工作代码,而不是
等。
“实现”。我不必重写整个类。我只需复制所有代码,并将“Impl2”更改为“Impl8”或其他内容。我只是觉得将来会有问题。每次我想更改单个实现时,都需要复制代码。Impl8是否继承Interface2?等等,为什么那些impl实例是公共的?
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;
...
};