为了在添加新实现时更灵活,您将如何重构这种多态设计?

时间:2016-09-28 22:58:04

标签: c++ oop inheritance polymorphism

我有一个具有许多虚函数的类,允许您获取对接口的引用。使用我的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?

1 个答案:

答案 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”(政策)存在用模板实现的策略模式)。