首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用部分通用实现设计C++类

使用部分通用实现设计C++类
EN

Stack Overflow用户
提问于 2013-07-12 22:37:17
回答 4查看 337关注 0票数 3

我正在设计一个C++模块。此模块可以接收3种不同类型的请求:请求-A、请求-B和请求-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失败,我们应该用不同的数据重试。但也许我想得太远了。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-07-12 23:16:21

“通用实现”意味着您的解决方案与继承无关。继承是为了接口重用,而不是实现重用。

你会发现你有通用的代码,只需使用共享函数:

代码语言:javascript
复制
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 (或使用匿名名称空间)以获得内部链接。

票数 4
EN

Stack Overflow用户

发布于 2013-07-12 22:51:56

你在找这样的东西吗?

代码语言:javascript
复制
#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
EN

Stack Overflow用户

发布于 2013-07-12 22:45:54

您可以使用一个基类来实现这5个操作,并从中派生处理程序。

如果这些操作彼此之间充分隔离,那么您也可以将它们分离到单独的函数或类中,并让处理程序调用它们。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17617471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档