我在项目中使用模板方法模式,如下所示:
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的答案都对我有用:)
非常感谢。
答案 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;
}
然后在Template
和Template2
之间有一个共同祖先:
class AbstractTemplate
{
public:
virtual void algorithm()=0;
}
最后将Template
和Template2
实现为“最终”类(不需要子类)。
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();
}
}
Template
和Template2
之间的重叠很小(考虑到您不需要子类,我认为可以)。