工厂模式 弃

工作场景:编写一个给用户发送短信的程序

传统写法

传统写法
#include <stdio.h>
#include <string>

enum NotifMessageType
{
    WUDI,
    FEITIAN
};

class NotifMessage
{
public:
    int sendMessage(long long userId, std::string& msg, NotifMessageType type)

    {
        std::string phoneNumber = "123666666";
        if (type == WUDI) {
            // 代发短信公司的代码接口     
        }
        else if(type == FEITIAN) {
            // 另一个代发短信公司的代码接口
        }
        return 0;
    }
};

int main()
{
    return 0;
}

int sendMessage()一个向用户发送信息的接口,需要知道用户的id,发送内容,发送短信是否成功的状态码来返回给int

enum NotifMessageType利用枚举类型根据条件判断判断是哪个公司的代码接口

像上述如果根据情况需要接入的接口越来越多,需要写的if else语句越来越冗长,该怎么解决呢

简单工厂模式

简单工厂模式
//Message.h类
#pragma once

#include <string>

class Message
{
public:
	virtual int sendMessage(const std::string & number, const std::string & content) = 0;
};

//XiaojiuziMessage.h
#pragma once

#include "MessageFactory.h"

class XiaojiuziMessageFactory : public MessageFactory
{
public:
	virtual Message* createMessage() override;
};



//XiaojiuziMessage.cpp
#include "XiaojiuziMessageFactory.h"

#include "XiaojiuziMessage.h"

Message* XiaojiuziMessageFactory::createMessage()
{
	std::string appid = "123456";
	std::string secret = "adjksfhjdaskfhksa";
	return new XiaojiuziMessage(appid, secret);
}

//main.cpp
#include <iostream>

#include "XiaojiuziMessage.h"
#include "DayiziMessage.h"

#include "SimpleMessageFactory.h"

#include "MessageFactory.h"
#include "XiaojiuziMessageFactory.h"
#include "DayiziMessageFactory.h"

int main()
{
	MessageFactory* mf = new DayiziMessageFactory();

	Message* message = mf->createMessage();
	message->sendMessage("12633333333", "短信来喽!!!");

	delete message;
	delete mf;
	return 0;
}

//SimpleMessageFactory.h
#pragma once

#include "Message.h"

enum MessageType
{
	Xiaojiuzi,
	Dayizi
};

class SimpleMessageFactory
{
public:
	static Message* createMessage(MessageType type);
};

//SimpleMessageFactory.cpp
#include "SimpleMessageFactory.h"

#include "XiaojiuziMessage.h"
#include "DayiziMessage.h"

Message* SimpleMessageFactory::createMessage(MessageType type)
{
	if (type == Xiaojiuzi) {
		std::string appid = "123456";
		std::string secret = "adjksfhjdaskfhksa";
		return new XiaojiuziMessage(appid, secret);
	}
	if (type == Dayizi) {
		std::string appid = "567";
		std::string secret = "ewqevcxdsga";
		std::string publickey = "sdjafhjkfhjadskhfjkadshfjkashfas";
		return new DayiziMessage(appid, secret, publickey);
	}
	return nullptr;
}

代码讲解:

  • Message.h作为基类,里面有一个纯虚函数virtual int sendMessage()抽象了业务代码交给子类重写
  • XiaojiuziMessage头文件表明重写,源文件实现发送要求代发的内容,
  • main.cpp
    image
    调用了父类的指针实现了子类虚函数的具体实现
  • 封装创建对象的类(工厂模式的底子)
    • SimpleMessageFactory里使用枚举封装接口名,导入基类使用静态成员creat函数根据接口名来返回创建子类对象对应的父类指针重写虚函数,
	if (type == Xiaojiuzi) {
		std::string appid = "123456";
		std::string secret = "adjksfhjdaskfhksa";
		return new XiaojiuziMessage(appid, secret);
	}

Message* message = mf->createMessage();传入一个接口名就可以了

好处:实现了代码逻辑与业务分离,只需要message基类交替给新创建的业务成员重写,main函数使用基类指针调用其对应的虚函数,如果有其他的新成员只需要包含头文件实现即可,每个类都是独立的类,缩小了修改的范围,如果一个类不需要了直接删除相关类
缺点:creat函数只是new一个对象,每个子类对象的初始化可能需要的参数不一样,这样会使得creat函数逻辑越来越复杂

在小舅子类创建一个构造函数image
image
在creat的时候将传入的成员变量赋值给小舅子的成员变量用来构造,其他业务类也是一样的逻辑,区别就在于其他的类需要的参数可能不一样

工厂模式

思路:生成业务对象的工厂类进行抽象被继承,让每一种业务类创建使用子工厂生成其对应的对象,接口类继承自抽象接口工厂类,业务类继承自mesage抽象类,修改都不会影响到对方

工厂模式
//MessageFactory.h
#pragma once

#include "Message.h"
#include "OverseaMessage.h"

class MessageFactory
{
public:
	//可被重写
	virtual Message* createMessage() = 0;
	virtual OverseaMessage * createOverseaMessage() = 0;
};

//XiaojiuziMessageFactory.cpp
#include "XiaojiuziMessageFactory.h"

#include "XiaojiuziMessage.h"
#include "XiaojiuziOverseaMessage.h"

Message* XiaojiuziMessageFactory::createMessage()
{
	std::string appid = "123456";
	std::string secret = "adjksfhjdaskfhksa";
	return new XiaojiuziMessage(appid, secret);
}

OverseaMessage* XiaojiuziMessageFactory::createOverseaMessage()
{
	return new XiaojiuziOverseaMessage();
}

//XiaojiuziMessageFactory.h
#pragma once

#include "MessageFactory.h"

class XiaojiuziMessageFactory : public MessageFactory
{
public:
	virtual Message* createMessage() override;
	virtual OverseaMessage* createOverseaMessage() override;
};

//main.cpp
#include <iostream>

#include "XiaojiuziMessage.h"
#include "DayiziMessage.h"

#include "SimpleMessageFactory.h"

#include "MessageFactory.h"
#include "XiaojiuziMessageFactory.h"
#include "DayiziMessageFactory.h"

int main()
{
	MessageFactory* mf = new DayiziMessageFactory();

	Message* message = mf->createMessage();
	message->sendMessage("12633333333", "短信来喽!!!");

	OverseaMessage * overseaMessage = mf->createOverseaMessage();

	delete message;
	delete mf;
	return 0;
}

代码讲解:image

  • MessageFactory创建子类对象的方法设置为虚函数,交由XiaojiuziMessageFactory类自己重写代码逻辑。
  • MessageFactory* mf = new DayiziMessageFactory();使用抽象生产类生产业务对象,再使用该父类指针调用短信发信,业务对象改变创建对象名就可以了,
  • 如果需要改变接口公司,创建一个类继承masseage,image
  • 创建其发送对象的工厂类继承自messagefactoryimage

抽象工厂模式

image

工作场景:国外发送信息不仅需要号码和内容还需要跨国代码,这样message就无法使用,所以需要被重写

抽象工厂类
//OverseaMessage.cpp
#pragma once

#include <string>

class OverseaMessage
{
public:
	virtual int sendMessage(const std::string & number, const std::string & content, const std::string & code) = 0;
};

//XiaojiuziOverseaMessage
#include "XiaojiuziOverseaMessage.h"

int XiaojiuziOverseaMessage::sendMessage(const std::string& number, const std::string& content, const std::string& code)
{
	printf("XiaojiuziOverseaMessage sendMessage\n");
	return 0;
}

//OverseaMessage.h
#pragma once

#include "OverseaMessage.h"

class XiaojiuziOverseaMessage : public OverseaMessage
{
public:
	virtual int sendMessage(const std::string& number, const std::string& content, const std::string& code) override;
};

//重用之前创建对象的工厂类在原有类添加,工厂模式代码里面

同样是业务继承自OverseaMessage类,实现sendmassage函数,工厂模式复用![image](https://img2023.cnblogs.com/blog/3124760/202309/3124760-20230924112723180-1479455131.png)之前的工厂代码里面添加个重写函数就可以了,一个factory用于创建不同message对象的能力!

区别:抽象工厂模式工厂可以创建不同类型对象实例,不同类型的实例由一定的关联度

posted @ 2023-09-24 10:05  游客0721  阅读(17)  评论(0)    收藏  举报