23个设计模式之工厂方法设计模式

 

工厂方法的意图

工厂方法主要用来创建对象,但是,具体创建什么对象,由子类来实现,父类只是封装一个虚创建对象的方法

抽象工厂的好处是在接口类中绕开的new的使用,避免因为需求变化而频繁的修改接口类,提高接口类的可复用性和可扩展性(易于维护),从而降低接口类对变化的依赖

 

举例

我们在做文档时,有时需要用Word,有时需要做PPT,还有时用Excel,所以,当我们创建不同类型的文件时,需要new不同的文档对象,这时,为了在不在接口或者基类中频繁修改new的对象,就可以使用工厂方法设计模式

 

代码如下

头文件

products.h

#ifndef PRODUCTSHEADFILE
#define PRODUCTSHEADFILE

#include <iostream>
#include <cassert>

using namespace std;

class fileinstance//产品接口(基类)
{
public:
	fileinstance() {cout<<__func__<<endl;}
	virtual ~fileinstance(){cout<<__func__<<endl;}

	virtual void file()=0;
};

class word:public fileinstance//具体的产品
{
public:
	word(){cout<<__func__<<endl;}
	~word(){cout<<__func__<<endl;}

	virtual void file();
};

class ppt:public fileinstance//具体的产品
{
public:
	ppt(){cout<<__func__<<endl;}
	~ppt(){cout<<__func__<<endl;}

	virtual void file();
};

class excel:public fileinstance//具体的产品
{
public:
	excel(){cout<<__func__<<endl;}
	~excel(){cout<<__func__<<endl;}

	virtual void file();
};

#endif

factorymethod.h

#ifndef FACTORYHEADFILE
#define FACTORYHEADFILE

#include "products.h"

class creatfilefactory//工厂接口(基类)
{
public:
	creatfilefactory(){cout<<__func__<<endl;}
	virtual ~creatfilefactory(){cout<<__func__<<endl;}

	virtual fileinstance *creatfile()=0;//创建产品对象,返回抽象产品对象的指针,在子类中实现
};

class wordfactory:public creatfilefactory//具体文件的工厂
{
public:
	wordfactory(){cout<<__func__<<endl;}
	~wordfactory(){cout<<__func__<<endl;}

	virtual fileinstance *creatfile();
};

class pptfactory:public creatfilefactory//具体文件的工厂
{
public:
	pptfactory(){cout<<__func__<<endl;}
	~pptfactory(){cout<<__func__<<endl;}

	virtual fileinstance *creatfile();
};

class excelfactory:public creatfilefactory//具体文件的工厂
{
public:
	excelfactory(){cout<<__func__<<endl;}
	~excelfactory(){cout<<__func__<<endl;}

	virtual fileinstance *creatfile();
};

#endif

run.h

#ifndef RUNHEADFILE
#define RUNHEADFILE

#include "factorymethod.h"

class run
{
public:
	run(creatfilefactory *factory);//接受具体工厂的指针参数
	~run();
	void startrun();

private:
	creatfilefactory *m_factory;
};

#endif

源文件

products.cpp

products.cpp
#include "products.h"

void word::file()
{
	cout<<"word will be created"<<endl;
}

void ppt::file()
{
	cout<<"ppt will be created"<<endl;
}

void excel::file()
{
	cout<<"excel will be created"<<endl;
}

factorymethod.cpp

#include "factorymethod.h"

fileinstance *wordfactory::creatfile()
{
	return new word();
}

fileinstance *pptfactory::creatfile()
{
	return new ppt();
}

fileinstance *excelfactory::creatfile()
{
	return new excel();
}

run.cpp

#include "run.h"

run::run(creatfilefactory *factory)
{
	cout<<__func__<<endl;
	m_factory=factory;
}

run::~run()
{
	cout<<__func__<<endl;
	if (m_factory) {
		delete m_factory;
		m_factory=nullptr;
	}
}

void run::startrun()
{
	cout<<__func__<<endl;
	fileinstance *instance=m_factory->creatfile();//多态创建工厂
	instance->file();//多态生成文件
}

main.cpp

#include "run.h"

int main(int argc, char const *argv[])
{
	run r(new pptfactory());//将易变化的代码(new pptfactory())限制在main函数中
	r.startrun();

	return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)  
project( dect_rect )  
INCLUDE_DIRECTORIES(include)
AUX_SOURCE_DIRECTORY(src DIR_SRCS)
add_executable(factorymethod ./src/products.cpp ./src/factorymethod.cpp ./src/run.cpp ./src/main.cpp)  

运行结果

如果要创建Word文件,只需要在main函数中修改r的参数,修改后重新编译运行的结果如下

可以看到只编译了main函数,而其他文件中的代码并没有参与编译,这样就降低了工厂基类和产品基类对变化部分(main)的依赖,提高了工厂基类和产品基类的模块化程度(耦合性降低),而且工厂基类和产品基类的可复用性和扩展性也更高

 

参考:

https://www.bilibili.com/video/BV1kW411P7KS?p=8

《设计模式,可复用面向对象软件的基础》

欢迎大家评论交流,作者水平有限,如有错误,欢迎指出

发布了7 篇原创文章 · 获赞 9 · 访问量 8638

猜你喜欢

转载自blog.csdn.net/Master_Cui/article/details/105323794