• Openssl数据安全传输平台008:业务数据分析+工厂方法


    0 代码仓库

    https://github.com/Chufeng-Jiang/OpenSSL_Secure_Data_Transmission_Platform/tree/main/Preparation/07.%E5%B7%A5%E5%8E%82%E7%B1%BB%E7%BC%96%E7%A0%81%E8%A7%A3%E7%A0%81-%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81/EncDecCode

    1 对本项目工厂类的理解

    在这里插入图片描述

    创建一个工厂factory = new RequestFactory(&info),调用工厂中的创建编解码的方法创建编解码对象RequestCodec(m_info),命名为codec,再调用codec中的编解码方法encodeMsg(),对编码对象进行编解码输出到str。

    syntax = "proto3";
    message RequestMsg
    {
        int32 cmdType = 1;
        bytes clientID = 2;
        bytes serverID = 3;
        string sign = 4; //此处为客户端信息独有
        string data = 5;
    }
    
    message RespondMsg
    {
        int32 status = 1;
        int32 seckeyID = 2; //此处为服务端信息独有
        bytes clientID = 3;
        bytes serverID = 4;
        string data = 5;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
      1. 因为客户端和服务端的数据信息不同,所以要使用不同的工厂类对数据信息分别进行编码解码
    CodecFactory* factory = new RequestFactory(&info); 
    
    • 1

    此时根据传参不同,m_flag区分该工厂初始化为编码或者解码.

    RequestFactory::RequestFactory(std::string enc) : CodecFactory()
    {
    	m_flag = false;
    	m_encStr = enc;
    }
    
    RequestFactory::RequestFactory(RequestInfo * info) : CodecFactory()
    {
    	m_flag = true;
    	m_info = info;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 2.创建工厂类。
    • 2.1 使用工厂类创建编码对象,命名为codec
    Codec* codec = factory->createCodec();
    
    • 1
    • 2.2 由第1部分决定m_flag的值,然后创建编解码对象。
    Codec * RequestFactory::createCodec()
    {
    	Codec* codec = NULL;
    	
    	if (m_flag) //m_flag = true;,则就是编码对象
    	{
    		codec = new RequestCodec(m_info);  
    	}
    	else
    	{
    		codec = new RequestCodec(m_encStr);
    	}
    	return codec;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 2.3 调用初始化编解码对象的方法
    RequestCodec::RequestCodec(RequestInfo *info)
    {
    	initMessage(info);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 2.4 初始化编解码对象内部实现
    void RequestCodec::initMessage(RequestInfo *info)
    {
    	m_msg.set_cmdtype(info->cmd);
    	m_msg.set_clientid(info->clientID);
    	m_msg.set_serverid(info->serverID);
    	m_msg.set_sign(info->sign);
    	m_msg.set_data(info->data);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
      1. 对编解码对象进行编解码
    string str = codec->encodeMsg();
    
    • 1
    • 3.1 编解码的内部实现
    string RequestCodec::encodeMsg()
    {
    	string output;
    	m_msg.SerializeToString(&output);
    	return output;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2 简单工厂模式 - 只需要一个工厂类

    工厂: 使用一个单独的类来做创建实例的过程, 这就是工厂。

    简单工厂:把对象的创建放到一个工厂类中,通过参数来创建不同的对象。
    特点:

    • 缺点:每添一个对象,就需要对简单工厂进行修改(尽管不是删代码,仅仅是添一个switch case,但仍然违背了“不改代码”的原则)
    • 优点:去除了与具体产品的依赖, 实现简单。
    # 简单工厂模式的使用:
    1. 创建一个工厂类
    2. 在这个类中提供一个公共的成员方法
        - 创建对象, 一般情况下创建某些实现多态的子类对象
        - 返回这个对象的地址
    
    • 1
    • 2
    • 3
    • 4
    • 5
    // 通过创建工厂类, 添加工厂函数, 创建对象
    // 两个编解码的子类
    class RequestCodec : public Codec    // 编解码请求数据
    class RespondCodec : public Codec    // 编解码响应数据
    
    
    // 创建工厂类, 创建编解码对象
    class Factory
    {
    public:
        Factory();
        ~Factory();
        // 工厂函数, 创建对象
        // flag==1 -> RequestCodec
        // falg==2 -> RespondCodec
        Codec* createObject(int flag)
        {
            Codec* c = NULL;
            // 判断
            if(flag == 1)
            {
                c = new RequestCodec();
            }
            else if(flag == 2)
            {
                c = new RespondCodec();
            }
            return c;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    工厂类的使用:

    // 1. 创建工厂类对象
    Factory* fac = new Factory;
    // 2. 通过工厂函数创建编解码对象
    Codec* c = fac->createObject(1);
    // 3. 编码
    string str = c->encoceMsg();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3 工厂模式 - 需要有N个工厂类

    工厂方法:每种产品由一种工厂来创建,一个工厂保存一个new

    特点:基本完美,完全遵循 “不改代码”的原则

    # 工厂模式流程
    1. 创建一个工厂类的基类
    2. 在这个基类中定义一个虚函数 -> 创建对象的方法
    3. 创建子工厂类(编解码的基类有多少子类, 就创建多少个子工厂类)
        - 每个编解码的子类, 都对应一个工厂类
    4. 在子工厂类中重写工厂类基类中的虚函数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4 UML图

    在这里插入图片描述

    在这里插入图片描述

    5 本项目案例图

    复制到画图中可放大查看
    在这里插入图片描述

    6 工厂类的使用:

    5.1 创建编解码的子类

    RequestCodec用于客户端数据的编解码
    RespondCodec用于服务端数据的编解码

    // 两个编解码的子类
    class RequestCodec : public Codec
    class RespondCodec : public Codec
    class TestCodec : public Codec    // 编解码响应数据
    
    • 1
    • 2
    • 3
    • 4

    5.2 创建工厂父类和子类

    父类中右一个虚拟方法,子类继承该方法后需要根据各自需求重写该方法。

    // 创建工厂类的基类
    class BaseFactory
    {
    public:
        BaseFactory();
        ~BaseFactory;
        virtual Codec* createCodec()
        {
            //待重写
            return NULL;
        }
    }
    
    // 工厂类子类
    class RequestFactory : public BaseFactory
    {
    public:
        RequestFactory();
        ~RequestFactory;
        
        Codec* createCodec()
        {
            return new RequestCodec; // 方法重写
        }
    }
    
    // 工厂类子类
    class RespondFactory : public BaseFactory
    {
    public:
        RespondFactory();
        ~RespondFactory;
        Codec* createCodec()
        {
            return new RespondCodec; // 方法重写
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    5.3 工厂模式使用

    // 1. 创建工厂类对象
    BaseFactory* fac = new RespondFactory;
    
    // 2. 通过工厂创建了编解码对象
    Codec* c = fac->createCodec();
    
    // 3. 使用编解码对象对数据进行编解码
    string str = c->encodeMsg();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    每日一题-字典
    我的创作纪念日
    宝塔上的wordpress站点更换域名+配置SSL+改版百度收录
    php摄影图片相册分享网站管理系统mysql
    dubbo 服务跟踪
    立创EDA导出元件的AD封装报错的解决方法
    TCP优化二:TCP 四次挥手性能优化
    什么是运维自动化巡检?
    信息熵,交叉熵,KL散度,互信息一网打尽
    计算机毕业设计ssm达梦商城-跨平台多商户电商平台nc9f0系统+程序+源码+lw+远程部署
  • 原文地址:https://blog.csdn.net/jiangchufeng123/article/details/133938260