Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
设计C++;具有部分通用实现的类 我正在设计一个C++模块。此模块可接收3种不同类型的请求:请求A、请求B和请求C。 对于每种类型,我都有一个相应的处理程序类:RequestHandler-a、RequestHandler-B和RequestHandler-C(所有这些都实现了IRequestHandler接口)。 每个处理程序都必须执行某些操作以满足其请求。 例如,RequestHandler-A需要按顺序执行这些操作: 行动1 行动2 行动3 行动4 行动-5_C++_Oop_Design Patterns - Fatal编程技术网

设计C++;具有部分通用实现的类 我正在设计一个C++模块。此模块可接收3种不同类型的请求:请求A、请求B和请求C。 对于每种类型,我都有一个相应的处理程序类:RequestHandler-a、RequestHandler-B和RequestHandler-C(所有这些都实现了IRequestHandler接口)。 每个处理程序都必须执行某些操作以满足其请求。 例如,RequestHandler-A需要按顺序执行这些操作: 行动1 行动2 行动3 行动4 行动-5

设计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

RequestHandler-B需要按顺序执行这些操作:
行动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
需要做的事情基本相同,但根据请求/处理程序类型略有不同,那么是时候将其作为函数模板了。感谢您提醒继承是为了接口重用,不是实现重用。我相信您正在混合命令模式和责任链模式。