简单工厂模式 C++实现

本文介绍了简单工厂模式的概念,并通过一个加减法运算器的例子展示了如何在C++中实现该模式。文章指出,简单工厂模式能实现客户端与具体实现类的解耦,但可能违反“开放——封闭原则”。为了解决这个问题,作者提到了使用工厂方法模式作为替代方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以前看设计模式,一直没怎么看懂,现在看了,懂了点皮毛,记录下来,方便自己以后不断改进。

先看一个简单的例子,一个小学生刚刚接触算术,开始学习整数加减法,请你帮他设计一个加减法运算器,你会怎么解决?

#include<stdio.h>
int main()
{
	int a,b;
	char operation;
	int result;
	scanf("%d%c%d",&a,&operation,&b);
	switch(operation)
	{
	case '+':
		result=a+b;
		break;
	case '-':
		result=a-b;
		break;
	}
	printf("result=%d\n",result);
	return 0;
}
既然是设计模式,面向对象的设计思想,这种面向过程的解决方案,我们就不要写了。

我们可以定义一个抽象类Operation,定义两个数据成员和得到这两个数据成员的函数,还有一个纯虚函数GetResult(C++没有interface和abstract class的明显关键字,只能通过纯虚函数去定义接口和关键字)

class Operation
{
public:
    Operation(int numA,int numB)
    {
        numberA=numA;
        numberB=numB;
    }
    int GetNumberA()
    {
        return numberA;
    }
    int GetNumberB()
    {
        return numberB;
    }
    virtual int GetResult()=0;          //让子类去实现这个纯虚函数,不同的运算符实现不同的操作结果
private:
    int numberA;
    int numberB;
};
然后加法类和减法类继承这个Operation类
//加法类
class OperationAdd:public Operation
{
public:
    OperationAdd(int numA,int numB):Operation(numA,numB){}
    int GetResult()
    {
        int result=GetNumberA()+GetNumberB();
        return result;
    }
};
//减法类
class OperationSub:public Operation
{
public:
    OperationSub(int numA,int numB):Operation(numA,numB){}
    int GetResult()
    {
        int result=GetNumberA()-GetNumberB();
        return result;
    }
};
这个时候,我们在客户端进行调用,会怎么做

int main()
{
	Operation* operation=new OperationAdd(1,2);
	cout<<operation->GetResult()<<endl;
}
也就是说,我们知道接口和具体的实现类(加法类或者减法类)。如果我们只知道,而不知道具体的实现类呢。我们该怎么办。解决这个问题,就用到了简单工厂模式,我们可以创建一个工厂类,在工厂类里有一个创建接口的成员函数

//私有化构造函数,把工厂类做成工厂工具类,防止无谓的创建简单工厂实例
class OperationFactory
{
private:
        OperationFactory(){}
public:
        static Operation* CreateOperation(int numA,int numB,char operate)
	{
		Operation* oper=NULL;
		if(operate=='+')
			oper=new OperationAdd(numA,numB);
		else if(operate=='-')
			oper=new OperationSub(numA,numB);
		return oper;
	}
};
现在,我们在客户端进行调用
int main()
{
	Operation* operation=OperationFactory::CreateOperation(1,2,'+');
	cout<<operation->GetResult()<<endl;
}
这个时候,我们只需要知道接口Operation即可,而无需知道具体的实现类。这样,我们就将具体的实现类隔离起来了。你可能话说,那不就是把加法类和减法类的创建过程移植到了工厂里面了,是的,理解简单工厂方法模式,关键在于理解工厂类的位置。

代码实现如下

#include<iostream>
#include<string>
using namespace std;
class Api
{
public:
	virtual void Operation(string s)=0;
};

class ImpA:public Api
{
public:
	void Operation(string s)	{	cout<<"ImpA::"<<s<<endl;	}
};

class ImpB:public Api
{
public:
	void Operation(string s)	{	cout<<"ImpB::"<<s<<endl;	}
};

class Factory
{
private:
        Factory(){}
 public:
	static Api* CreateApi(int condition){
		Api* api=NULL;
		switch (condition)
		{
		case 1:
			api=new ImpA();
			break;
		case 2:
			api=new ImpB();
			break;
		default:
			api=NULL;
		}
		return api;
	}
};

int main()
{
	Api* api=Factory::CreateApi(2);
	api->Operation("helloworld");
	delete api;
}
工厂类介意客户端和内部实现之间,起到了桥梁的作用,隐藏了内部的实现。

当然,因为CreateApi是通过了判断条件来选择创建具体的类,这在一定程度上也暴露了内在的实现。简单工厂模式的实质就是选择实现。通过简单工厂,可以实现客户端和具体类的解耦,客户端根本就不知道到底是由谁来实现的,也就不知道具体是如何实现的,客户端只是通过工厂来获取它需要的接口对象。


小学生学习完了加减法之后,开始学习乘法了,这时候我们应该怎么做呢?你可能会说,继承Operation,新建一个新的OperationMul类,然后在简单工厂类里面加一个判断条件不就行了?添加一个新的OperationMul类没有问题,但是修改简单工厂类就不好了,因为这样就违反了“开放——封闭原则”,“开放—封闭”,是说软件实体(类、模块、函数等)可以进行扩展,但是不可修改。对于扩展是开放,对于更改是封闭的。

解决这个问题就需要用到另一个模式,工厂方法模式!



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值