使用部分常见的实现设计C ++类

时间:2013-07-12 14:37:17

标签: c++ oop design-patterns

我正在设计一个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失败,我们应该用不同的数据重试它。但也许我在想太远了。

4 个答案:

答案 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中。