模板方法模式:改变算法的架构

Template method pattern: changing the algorithm's architecture

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

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

我有一些子classes 以不同的方式实现方法 A & B
但是现在我需要一个新的 class 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 在所有子 class 中都是相同的,所以我没有将其设为虚拟。
现在我基于 Template2 创建了一个新的继承层次结构,但这看起来很愚蠢,因为我必须在这个新层次结构中复制并粘贴每个子 classes 的代码。
有什么更优雅的方式吗?

编辑
对不起,我没有表达清楚。
现在我有两个继承层次结构。
1. 一个摘要 class Template 和一些子classes A1,A2,A3,A4...
2. 一个摘要 class Template2 和一些子classes B1,B2,B3,B4...
这工作正常,但我想知道是否有办法以某种方式合并这两个层次结构,因为 A1 和 B1 具有相同的代码,只是它们分别派生自 Template 和 Template2。
解决方案是否为模板方法模式与我无关
bcperth 和 Spotted 的回答都对我有用:)
非常感谢。

首先,请原谅我糟糕的 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 实现为 "final" 类(=不需要 sub类)。

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 之间的重叠是最小的(考虑到你不需要 sub类,我认为没关系)。

我同意 Spotted,但您是否考虑过向 template class 添加其他算法?它仍然是具有多种算法的模板模式。你得到一个更胖的 class 但没有代码重复。下面是一个例子。

#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;
}