我正在设计一个C ++模块。该模块可以接收3种不同类型的请求:Request-A,Request-B和Request-C
对于每种类型,我都有一个相应的处理程序类:RequestHandler-A,RequestHandler-B和RequestHandler-C(所有这些都实现了IRequestHandler接口)。
每个处理程序必须执行某些操作以满足其请求
例如,RequestHandler-A需要按顺序执行这些:
动作1
动作2
动作3
动作4
行动-5
RequestHandler-B需要按顺序执行这些操作:
动作1
动作3
行动-5
RequestHandler-C需要按顺序执行这些操作:
动作4
行动-5
下一个操作将使用一个操作的结果。
我正在努力设计这些类,以便在处理程序之间重用常见的动作实现。 有没有可以在这里应用的设计模式?也许模板方法模式可能是一种可能,但我不确定。 任何建议都将不胜感激。
PS:为了让事情变得更有趣,还有一个要求,即如果Action-2失败,我们应该用不同的数据重试它。但也许我在想太远了。答案 0 :(得分:4)
“常见实现”意味着您的解决方案与继承无关。继承用于接口重用,而不是实现重用。
你发现你有共同的代码,只需使用共享功能:
void action1();
void action2();
void action3();
void action4();
void action5();
struct RequestHandlerA : IRequestHandler {
virtual void handle( Request *r ) {
action1();
action2();
action3();
}
};
struct RequestHandlerB : IRequestHandler {
virtual void handle( Request *r ) {
action2();
action3();
action4();
}
};
struct RequestHandlerC : IRequestHandler {
virtual void handle( Request *r ) {
action3();
action4();
action5();
}
};
假设公共函数只是内部帮助器,您可能希望使它们static
(或使用匿名命名空间)来获取内部链接。
答案 1 :(得分:2)
你在找这样的东西吗?
#include <iostream>
using namespace std;
class Interface{
public:
void exec(){
//prepare things up
vExec();
//check everything is ok
};
virtual ~Interface(){}
protected:
virtual void vExec() = 0;
virtual void Action0() = 0;
virtual void Action1(){}
void Action2(){}
};
void Interface::Action0(){
}
void Action3(){}
class HandlerA : public Interface{
protected:
virtual void vExec(){
Action0();
Action1();
Action3();
}
virtual void Action0(){
}
};
class HandlerB : public Interface{
protected:
virtual void vExec(){
Action0();
Action1();
Action2();
Action3();
}
virtual void Action0(){
Interface::Action0();
}
};
int main()
{
Interface* handler = new HandlerA();
handler->exec();
HandlerB b;
b.exec();
delete handler;
}
正如您所看到的,这些操作可以是虚拟成员,非虚拟成员,免费功能或您可能想到的任何内容,具体取决于您的需求。
使用不同数据提供操作的“附加”功能可以在exec()中执行(如果是通用的)或在vExec中执行(如果它是特定于处理程序的)。如果您提供更多详细信息,我可以相应地修改示例。
此外,您可以使vExec公开并摆脱exec。示例中的那个只是我最喜欢的一种做法(使接口非虚拟和虚拟功能非公开)。
答案 2 :(得分:1)
您可以拥有一个实现5个操作的基类,并让处理程序从中派生。
如果动作彼此充分隔离,你可以将它们分成单独的函数或类,只需让处理程序调用它们。
答案 3 :(得分:0)
您是否考虑过Command Of Command设计模式? http://en.wikipedia.org/wiki/Command_pattern
这是一种经过时间验证的模式,可以促进处理程序对象与它们接收的请求(命令)之间的松散耦合。
您可以做的是将请求对象转换为命令对象。然后,您可以指定每个处理程序可以执行的命令类型。然后,您可以将命令传递给处理程序,如果它们无法处理它们,请让它们向前传递命令。如果处理程序可以处理该操作,则通过其各自的Actions处理该命令。然后,您可以使用合成将每个逻辑操作作为对象本身驻留在Handler中。