在具有多态特性的类体系中,向客户提供使用接口,而不去暴露类的体系结构。

news/2024/5/18 22:29:13 标签: struct, class, signal, delete, null, io
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

先举个例子,我们在开发中,经常会处理很多异步消息,比如:io消息、信号、定时器等,现在我们就建立一个消息处理器系统,代码如下:


class="tags" href="/tags/STRUCT.html" title=struct>struct msg
{
    int msg_id;


    char data[1];
};
class BaseMsgProcessor
{
public:
    virtual int process_msg(class="tags" href="/tags/STRUCT.html" title=struct>struct msg *msg)
    {
        std::cout << "process general msg/n";
        return 0;
    }
};

class IOMsg : public BaseMsgProcessor
{
public:
    virtual int process_msg(class="tags" href="/tags/STRUCT.html" title=struct>struct msg *msg)
    {
        std::cout << "process io msg/n";
        return 0;
    }
};

class TimeOutMsg : public BaseMsgProcessor
{
public:
    virtual int process_msg(class="tags" href="/tags/STRUCT.html" title=struct>struct msg *msg)
    {
        std::cout << "process TimeOutMsg msg/n";
        return 0;
    }
};

class SignalMsg : public BaseMsgProcessor
{
public:
    virtual int process_msg(class="tags" href="/tags/STRUCT.html" title=struct>struct msg *msg)
    {
        std::cout << "process SignalMsg msg/n";
        return 0;
    }
};

 

上面的类结构,相当于像用户暴露了process_msg接口,用户会做如下的使用方法

 BaseMsgProcessor * processor = NULL;
   

    //io消息
    class="tags" href="/tags/STRUCT.html" title=struct>struct msg m;

    m.msg_type = MT_IO;
    processor = new IOMsg;
    processor->process_msg(&m);
    delete processor;
    processor = NULL;

 

    //超时消息
    m.msg_type = MT_TIMEOUT;
    processor = new TimeOutMsg;
    processor->process_msg(&m);
    delete processor;
    processor = NULL;

 

    //处理信号
    m.msg_type = MT_SIGNAL;
    processor = new SignalMsg;
    processor->process_msg(&m);
    delete processor;
    processor = NULL;

 

这里的问题在哪里呢?

1、用户需要识别不同的消息处理器,有时这个识别逻辑可能比较复杂,所以容易出错。而原本这个消息处理器体系结构的组织、规划,是程序作者最清楚的。

2、需要负责处理器实例的创建、回收。有时,我们处理器的实例并不是通过简单的new/delete,创建、释放的,所以这个过程容易让用户产生使用上的错误。

 

如果“消息处理器”的作者,把整个使用过程都提供出来,就可以易用许多。如下:


enum msg_type
{
    MT_IO,
    MT_TIMEOUT,
    MT_SIGNAL
};

class="tags" href="/tags/STRUCT.html" title=struct>struct msg
{
    int msg_id;
    int msg_type;
    char data[1];
};
class BaseMsgProcessor
{
public:
    static int process(class="tags" href="/tags/STRUCT.html" title=struct>struct msg *msg)
    {

        BaseMsgProcessor * processor = Factory(msg->msg_type);

        if (!processor)
            return -1;

        class="tags" href="/tags/STRUCT.html" title=struct>struct msg m;

       
        int r = processor->process_msg(&m);

        delete processor;
        processor = NULL;

        return r;
    }

    static BaseMsgProcessor * Factory(int msg_type)
    {
        BaseMsgProcessor *process = NULL;
        switch(msg_type)
        {
        case MT_IO:
process = new IOMsg;
        case MT_SIGNAL:
            process = new SignalMsg;
        case MT_TIMEOUT:
            process = new TimeOutMsg;
        default:
            ;
        }

        return process;
    }
    private:
    virtual int process_msg(class="tags" href="/tags/STRUCT.html" title=struct>struct msg *msg)
    {
        std::cout << "process general msg/n";
        return 0;
    }
};

class IOMsg : public BaseMsgProcessor
{
private:
    virtual int process_msg(class="tags" href="/tags/STRUCT.html" title=struct>struct msg *msg)
    {
        std::cout << "process io msg/n";
        return 0;
    }
};

class TimeOutMsg : public BaseMsgProcessor
{
private:
    virtual int process_msg(class="tags" href="/tags/STRUCT.html" title=struct>struct msg *msg)
    {
        std::cout << "process TimeOutMsg msg/n";
        return 0;
    }
};

class SignalMsg : public BaseMsgProcessor
{
private:
    virtual int process_msg(class="tags" href="/tags/STRUCT.html" title=struct>struct msg *msg)
    {
        std::cout << "process SignalMsg msg/n";
        return 0;
    }
};

 

用户只需要调用一下process,不用关心 process内部的细节

 class="tags" href="/tags/STRUCT.html" title=struct>struct msg m;

    BaseMsgProcessor::process(&m);

 


http://www.niftyadmin.cn/n/1870227.html

相关文章

求出32位整数左边第一位是1的算法

算法思路&#xff1a; 总体采用分治法 1、先将32位分成两个16位 2、在16位中再分析出8为&#xff0c;依次类推 unsigned ffs(unsigned n){ if (n 0) return 0; unsigned c 32; if (!(n & 0xffff0000)) { c - 16; n << 16; } …

c++中的左移、右移运算

移位运算包含“逻辑移位”&#xff08;logical shift&#xff09;和“算术移位”&#xff08;arithmetic shift&#xff09;。 逻辑移位&#xff1a;移出去的位丢弃&#xff0c;空缺位&#xff08;vacant bit&#xff09;用 0 填充。 算术移位&#xff1a;移出去的位丢弃&…

c++的模运算

在数学里&#xff0c;“模运算”也叫“求余运算”&#xff0c;用mod来表示模运算。 对于 a mod b 可以表示为 a qb r&#xff0c;其中q表示商&#xff0c;b表示模数且 b ! 0&#xff0c;那么余数 r 满足 0 < |r| < |b|。 如果a和b都是自然数&#xff0c;那么r肯定大于…

整数在计算机中的表示

整数包含正整数&#xff0c;负整数和0。从数学的角度来讲&#xff0c;整数是无穷无尽、列举不完的&#xff0c;整数的大小是没有限制的。但是&#xff0c;如果用计算机来表示整数&#xff0c;则不然。因为计算机是靠数字信号来表示数&#xff0c;计算机所能处理的整数的长度也是…

JDBC之获取插入语句返回的主键

该获取主键并不是绝对的&#xff0c;也和具体的数据库实现的驱动有关。 package cn.itcast.jdbc; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.junit.T…

整数的加法运算

1.1.1 无符号整数加法 假设x&#xff0c;y都是比特位为w的无符号整数&#xff0c;那么x和y分别可以表示为&#xff0c; 0 < x < 2w&#xff0c;0 < y < 2w&#xff0c;0 < xy < 2w1 &#xff0c;xy的结果需要 w1位来表示。如果只有w位来表示两个无符号整数…

从零开始玩转JMX(一)——简介和Standard MBean

JMX的全称为Java Management Extensions. 顾名思义&#xff0c;是管理Java的一种扩展。这种机制可以方便的管理、监控正在运行中的Java程序。常用于管理线程&#xff0c;内存&#xff0c;日志Level&#xff0c;服务重启&#xff0c;系统环境等。 简介 基本术语 MBean&#xff1…

数据的字节对齐(data structure alignment)

1.1.1 为什么需要字节对齐 1、处理器的差异 有的处理器&#xff0c;不容许在字节未对齐的地址上访问字或者是多个字的数据。比如sun sparc cpu&#xff0c;不容许在奇数字节上访问一个字&#xff0c;否则会出现异常。 2、出于CPU读取内存数据效率的考虑。 CPU访问内存的时…