模板方法模式:改变算法的架构
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;
}
然后在Template
和Template2
之间有一个共同的祖先:
class AbstractTemplate
{
public:
virtual void algorithm()=0;
}
最后将 Template
和 Template2
实现为 "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();
}
}
Template
和 Template2
之间的重叠是最小的(考虑到你不需要 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;
}
我在我的项目中使用模板方法模式,如下所示
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;
}
然后在Template
和Template2
之间有一个共同的祖先:
class AbstractTemplate
{
public:
virtual void algorithm()=0;
}
最后将 Template
和 Template2
实现为 "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();
}
}
Template
和 Template2
之间的重叠是最小的(考虑到你不需要 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;
}