天天看點

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、測試結果如下圖:

C++設計模式——工廠模式

注意:

可以看到,在執行個體化産品類時,參數均為一個double類型的變量,這也是工廠模式的一個缺陷,即要求建立方法的參數(個數、類型、順序)相同。例如,如果要建立一個長方形,給定長寬兩個參數的話,就無法實作這個模式,需要考慮另外的處理方式。

繼續閱讀