设计C++;具有部分通用实现的类 我正在设计一个C++模块。此模块可接收3种不同类型的请求:请求A、请求B和请求C。 对于每种类型,我都有一个相应的处理程序类:RequestHandler-a、RequestHandler-B和RequestHandler-C(所有这些都实现了IRequestHandler接口)。 每个处理程序都必须执行某些操作以满足其请求。 例如,RequestHandler-A需要按顺序执行这些操作: 行动1 行动2 行动3 行动4 行动-5
RequestHandler-B需要按顺序执行这些操作:设计C++;具有部分通用实现的类 我正在设计一个C++模块。此模块可接收3种不同类型的请求:请求A、请求B和请求C。 对于每种类型,我都有一个相应的处理程序类:RequestHandler-a、RequestHandler-B和RequestHandler-C(所有这些都实现了IRequestHandler接口)。 每个处理程序都必须执行某些操作以满足其请求。 例如,RequestHandler-A需要按顺序执行这些操作: 行动1 行动2 行动3 行动4 行动-5,c++,oop,design-patterns,C++,Oop,Design Patterns,RequestHandler-B需要按顺序执行这些操作: 行动1 行动3 行动-5 RequestHandler-C需要按顺序执行这些操作: 行动4 行动-5 一个操作的结果将被下一个操作使用 我正在努力设计这些类,以便在处理程序之间重用常见的操作实现。 这里是否有可以应用的设计模式?也许模板方法模式可能是一种可能性,但我不确定。 如有任何建议,将不胜感激 PS:为了让事情更有趣,还有一个要求,如果Action-2失败,我们应该使用不同的数据重试。但是也许我想得太远了。您可以有一个基类来实现这5
行动1
行动3
行动-5 RequestHandler-C需要按顺序执行这些操作:
行动4
行动-5 一个操作的结果将被下一个操作使用 我正在努力设计这些类,以便在处理程序之间重用常见的操作实现。 这里是否有可以应用的设计模式?也许模板方法模式可能是一种可能性,但我不确定。 如有任何建议,将不胜感激
PS:为了让事情更有趣,还有一个要求,如果Action-2失败,我们应该使用不同的数据重试。但是也许我想得太远了。您可以有一个基类来实现这5个操作,并让处理程序从中派生出来
如果操作彼此充分隔离,您可能也可以将它们分离为单独的函数或类,并让处理程序调用它们。您正在寻找类似的操作吗
#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;
}
#包括
使用名称空间std;
类接口{
公众:
void exec(){
//准备好
vExec();
//检查一切是否正常
};
虚拟~Interface(){}
受保护的:
虚拟void vExec()=0;
虚拟void Action0()=0;
虚拟void Action1(){}
void Action2(){}
};
void接口::Action0(){
}
void Action3(){}
类HandlerA:公共接口{
受保护的:
虚拟void vExec(){
动作0();
行动1();
行动3();
}
虚拟void Action0(){
}
};
类HandlerB:公共接口{
受保护的:
虚拟void vExec(){
动作0();
行动1();
行动2();
行动3();
}
虚拟void Action0(){
接口::Action0();
}
};
int main()
{
接口*handler=newhandlera();
handler->exec();
HandlerB;
b、 exec();
删除处理程序;
}
正如您所看到的,操作可以是虚拟成员、非虚拟成员、自由函数,或者您可能想到的任何东西,这取决于您需要什么
可以在exec()中(如果是泛型的)或在vExec中(如果是特定于处理程序的)执行向操作提供不同数据的“附加”功能。如果你给我们更多的细节,我可以修改相应的例子
此外,您还可以公开vExec,并删除exec。示例中的一个只是我最喜欢的实践(使界面非虚拟,虚拟功能非公共)。您考虑过命令链设计模式吗? 这是一种经过时间验证的模式,它促进了处理程序对象及其接收的请求(命令)之间的松散耦合 您可以做的是将请求对象转换为命令对象。然后指定每个处理程序可以执行的命令类型。然后,您可以将命令传递给处理程序,并让它们在无法处理命令时向前传递命令。如果处理程序可以处理该操作,则通过其各自的操作处理该命令。然后,您可以利用组合将每个逻辑操作作为对象本身驻留在处理程序中 “通用实现”意味着您的解决方案与继承无关。继承是为了接口重用,而不是实现重用 您发现您有通用代码,只需使用共享函数:
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();
}
};
假设公共函数只是内部助手,您可能希望使它们成为
静态的
(或使用匿名名称空间)以获得内部链接。或者,为每个函数(或函数集,即类ClassAction1{action1(){};
)让每个孩子继承他们需要的任何特定功能。这样,RequestHandler-C
甚至无法访问它不应该使用的函数。不过,将所有5个函数都放在同一个基类中(假设它们受到保护)更有意义。如果操作只是自由函数,那么生活会更轻松。模板方法模式的关注点分离非常差。听起来OP不希望操作是虚拟的,在本例中也不需要。但是,这并没有真正伤害XD。答案中指定了这一点:)不过,感谢您的确认!这或者,如果action2
需要做的事情基本相同,但根据请求/处理程序类型略有不同,那么是时候将其作为函数模板了。感谢您提醒继承是为了接口重用,不是实现重用。我相信您正在混合命令模式和责任链模式。