C++设计模式——工厂模式

工厂模式

很多博客都有工厂模式相关的理论介绍,就不照本宣科了,直接从问题出发。看代码:

#pragma once
#include<cmath>
const double PI = acos(-1.0);
class IGraph {
public:
	virtual double Area() = 0;//计算图形的面积
	virtual ~IGraph() {};
};

class Square :public IGraph {//正方形
public:
	Square(double Squarelen) :m_Squarelen(Squarelen) {}
	double Area() override {
		return m_Squarelen * m_Squarelen;
	}
private:
	double m_Squarelen;
};

class EqualTriangle :public IGraph {//等边三角形
public:
	EqualTriangle(double Trilen) :m_Trilen(Trilen) {}
	double Area() override {
		return	0.5 * m_Trilen * m_Trilen * sin(60 * PI / 180);
	}
private:
	double m_Trilen;
};

class Circle :public IGraph {//圆
public:
	Circle(double radius) :m_radius(radius) {}

	double Area() override {
		return m_radius * m_radius * PI;
	}
private:
	double m_radius;
};

1、定义一个图形抽象类,有一个计算图形面积的纯虚函数,有三个具体的图形继承它。该文件放在product.h头文件中。

class mainForm
{
public:
	mainForm(double d):data(d){}
	void Button_click()
	{
		IGraph* m_graph = new Circle(data);//依赖具体类
		data = m_graph->Area();
		cout << "show the area of graph:" << data << endl;
	}
private:
	double  data;
};

2、实际中,假设有一个窗口,有一个按钮点击函Button_click(),作用是弹出图形面积。可以看到当要弹出不同图形不的面积时,都需要更改第7行的代码,依赖于具体类的实现,每次新的变化来临时,都需要更改mainForm的代码,违背了开放封闭原则。此时就引入了工厂模式。定义一个工厂类如下:

#pragma once
#include"product.h"
class IFactoty {
public:
	virtual IGraph* CreateGraph(double data) = 0;//创建对象
	virtual ~IFactoty() {}
};

class SquareFactory :public IFactoty{
public:
	SquareFactory() {}
	IGraph* CreateGraph(double data) override {
		return new Square(data);
	}
};
class EqualTriangleFactory :public IFactoty {
public:
	EqualTriangleFactory() {}
	IGraph* CreateGraph(double data) override {
		return new EqualTriangle(data);
	}
};
class CircleFactory :public IFactoty {
public:
	CircleFactory() {}
	IGraph* CreateGraph(double data) override {
		return new Circle(data);
	}
};

3、创建一个抽象工厂类,每个新增加的图形都作为一个具体的工厂类继承该类,实现CreateGraph方法。实现每次新增一个图形时,只需要增加一个产品类和对应的工厂类,无需修改mainForm类的代码,达到解耦的目的,此时mainForm代码如下:

class mainForm
{
public:
	mainForm(IFactoty* factory, double d) {
		this->factory = factory;
		data = d;
	}
	void Button_click()
	{
		IGraph* m_graph = factory->CreateGraph(data);//无需再变更代码
		data = m_graph->Area();
		cout << "show the area of graph:" << data << endl;
	}
private:
	double  data;
	IFactoty* factory;
};

4、对应的测试代码如下:

int main()
{
	IFactoty* factory1 = new CircleFactory();
	mainForm* form1 = new mainForm(factory1,3);
	form1->Button_click();

	IFactoty* factory2 = new SquareFactory();
	mainForm* form2 = new mainForm(factory2, 3);
	form2->Button_click();

	IFactoty* factory3 = new EqualTriangleFactory();
	mainForm* form3 = new mainForm(factory3, 3);
	form3->Button_click();
	
	system("pause");
	return 0;
}

5、测试结果如下图:
在这里插入图片描述
注意:
可以看到,在实例化产品类时,参数均为一个double类型的变量,这也是工厂模式的一个缺陷,即要求创建方法的参数(个数、类型、顺序)相同。例如,如果要创建一个长方形,给定长宽两个参数的话,就无法实现这个模式,需要考虑另外的处理方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dailingGuo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值