模板方法模式:更改算法的体系结构

时间:2018-10-01 15:11:16

标签: oop design-patterns ooad

我在项目中使用模板方法模式,如下所示:

class Template
{
public:
void algorithm();
{
    A();
    B();
}
private:
virtual void A()=0;
virtual void B()=0;
}

我有一些子类以不同的方式实现方法 A B
但是现在我需要一个新的类 Template2 来实现稍微不同的算法。

class Template2
{
public:
void algorithm();
{
    A();
    B();
    C();
}
private:
virtual void A()=0;
virtual void B()=0;
void C()
{
    //some stuff
    A();
    //some stuff
    B();
}
}

C 在所有子类中都是相同的,因此我不会将其虚拟化。
现在,我基于 Template2 创建了一个新的继承层次结构,但这似乎很愚蠢,因为我必须在此新层次结构中复制并粘贴每个子类的代码。
无论如何,还有一种更优雅的方式吗?

EDIT
抱歉,我的意思不清楚。
现在我有两个继承层次结构。
1.一个抽象类Template和一些子类A1,A2,A3,A4...
2.抽象类Template2和某些子类B1,B2,B3,B4...
这很好用,但是我想知道是否有办法合并这两个层次结构,因为A1和B1具有相同的代码,只是它们分别来自Template和Template2。
解决方案是否为模板方法模式对我来说无关紧要
bcperth和Spotted的答案都对我有用:)
非常感谢。

2 个答案:

答案 0 :(得分:2)

我同意Spotted,但是您是否考虑过仅在template类中添加其他算法?其仍然具有多种算法的模板模式。您将获得一个更好的课程,但是没有代码重复。下面是一个说明。

#include <iostream>

using namespace std;

class Template
{
public:
    void algorithm1()
    {
        A();
        B();
    }

    void algorithm2()
    {
        A();
        B();
        C();
    }

private: void C()
    {
    cout << endl << "start C() ";
    A();
    cout << "middle C() ";
    B();
    cout << "end C()" << endl;
    }

private:
    virtual void A() = 0;
    virtual void B() = 0;
};

class real :public Template {

    void A() { cout << "A(1)  "; }
    void B() { cout << "B(1) "; }
};

int main()
{
    real Real;
    cout << "algorithm1" <<endl;
    Real.algorithm1();
    cout << endl;
    cout << endl << "algorithm2 << endl";
    Real.algorithm2();

    return 0;
}

答案 1 :(得分:1)

首先,请原谅我糟糕的C ++语法。

我建议您将A()B()Template分离,以便您可以更轻松地在Template2中重用它们

class Strategy
{
    public:
    virtual void A()=0;
    virtual void B()=0;
}

然后在TemplateTemplate2之间有一个共同祖先:

class AbstractTemplate
{
    public:
    virtual void algorithm()=0;
}

最后将TemplateTemplate2实现为“最终”类(不需要子类)。

class Template : AbstractTemplate
{
    public:
    Template(Strategy strategy)
    {
        this.strategy = strategy;
    }
    void algorithm()
    {
        strategy.A();
        strategy.B();
    }
    private:
    Strategy strategy;
}

class Template2 : AbstractTemplate
{
    public:
    Template2(Strategy strategy)
    {
        this.strategy = strategy;
    }
    void algorithm()
    {
        strategy.A();
        strategy.B();
        C();
    }
    private:
    Strategy strategy;
    void C()
    {
        //some stuff
        strategy.A();
        //some stuff
        strategy.B();
    }
}

TemplateTemplate2之间的重叠很小(考虑到您不需要子类,我认为可以)。