深入浅出设计模式——创建型模式之工厂模式

文章目录

在介绍简单工厂方法模式时Jungle总结出简单工厂模式存在最大的问题是违背了"开闭原则",每当增加新的产品时,需要修改工厂类的逻辑。为了规避这种不足,同时很好的利用简单工厂模式的优点,本节Jungle将声情并茂地为您奉上工厂方法模式。

为了解决简单工厂模式的这两个弊端,工厂方法模式应运而生,它规定每个产品都有一个专属工厂。比如苹果有专属的苹果工厂,梨子有专属的梨子工厂

工厂方法模式简介

简单工厂模式中,每新增一个具体产品,就需要修改工厂类内部的判断逻辑。为了不修改工厂类,遵循开闭原则,工厂方法模式中不再使用工厂类统一创建所有的具体产品,而是针对不同的产品设计了不同的工厂,每一个工厂只生产特定的产品。

工厂方法模式定义

工厂方法模式:

定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。

工厂方法模式结构


工厂方法模式代码实例

考虑这样一个场景,如下图:

Jungle想要进行户外运动,它可以选择打篮球、踢足球或者玩排球。和上一次的体育保管室不同,这次分别由篮球保管室、足球保管室和排球保管室.

Jungle只需直接去相应的保管室就可以拿到对应的球!然后Jungle就可以愉快地玩耍了。

定义抽象产品类AbstractSportProduct,方法不提供实现

cpp 复制代码
//抽象产品类AbstractProduct
class AbstractSportProduct
{
public:
	AbstractSportProduct(){
 
	}
	virtual ~AbstractSportProduct(){}
	//抽象方法:
	virtual void printName() = 0;
	virtual void play(){} = 0;
};

定义三个具体产品类

cpp 复制代码
//具体产品类Basketball
class Basketball :public AbstractSportProduct
{
public:
	Basketball(){
		printName();
		play();
	}
	//具体实现方法
	void printName(){
		printf("Jungle get Basketball\n");
	}
	void play(){
		printf("Jungle play Basketball\n\n");
	}
};
 
//具体产品类Football
class Football :public AbstractSportProduct
{
public:
	Football(){
		printName();
		play();
	}
	//具体实现方法
	void printName(){
		printf("Jungle get Football\n");
	}
	void play(){
		printf("Jungle play Football\n\n");
	}
};
 
//具体产品类Volleyball
class Volleyball :public AbstractSportProduct
{
public:
	Volleyball(){
		printName();
		play();
	}
	//具体实现方法
	void printName(){
		printf("Jungle get Volleyball\n");
	}
	void play(){
		printf("Jungle play Volleyball\n\n");
	}
};

定义抽象工厂类AbstractFactory,方法为纯虚方法

cpp 复制代码
//抽象工厂类
class AbstractFactory
{
public:
	virtual AbstractSportProduct *getSportProduct() = 0;
	virtual ~AbstractFactory(){}
};

定义三个具体工厂类

cpp 复制代码
/具体工厂类BasketballFactory
class BasketballFactory :public AbstractFactory
{
public:
	BasketballFactory(){
		printf("BasketballFactory\n");
	}
	AbstractSportProduct *getSportProduct(){
		printf("basketball");
		return new Basketball();
	}
};
 
//具体工厂类FootballFactory
class FootballFactory :public AbstractFactory
{
public:
	FootballFactory(){
		printf("FootballFactory\n");
	}
	AbstractSportProduct *getSportProduct(){
		return new Football();
	}
};
 
//具体工厂类VolleyballFactory
class VolleyballFactory :public AbstractFactory
{
public:
	VolleyballFactory(){
		printf("VolleyballFactory\n");
	}
	AbstractSportProduct *getSportProduct(){
		return new Volleyball();
	}
};

客户端使用方法示例

cpp 复制代码
#include <iostream>
#include "FactoryMethod.h"
 
int main()
{
	printf("工厂方法模式\n");
	
	//定义工厂类对象和产品类对象
	AbstractFactory *fac = nullptr;
	AbstractSportProduct *product = nullptr;
 
	fac = new BasketballFactory();
	product = fac->getSportProduct();
	delete fac;
	fac = nullptr;
	delete product;
	product = nullptr;
 
	fac = new FootballFactory();
	product = fac->getSportProduct();
	delete fac;
	fac = nullptr;
	delete product;
	product = nullptr;
 
	fac = new VolleyballFactory();
	product = fac->getSportProduct();	
	delete fac;
	fac = nullptr;
	delete product;
	product = nullptr;
 
	system("pause");
	return 0;
}

运行结果

工厂方法模式总结

如果Jungle想玩棒球(Baseball),只需要增加一个棒球工厂(BaseballFacory),然后在客户端代码中修改具体工厂类的类名,而原有的类的代码无需修改。由此可看到,相较简单工厂模式,工厂方法模式更加符合开闭原则。工厂方法是使用频率最高的设计模式之一,是很多开源框架和API类库的核心模式。

之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

相关推荐
高晶7 小时前
CANopen 在 BMS 系统中的 C 语言实战指南
设计模式·程序员
博风8 小时前
13、设计模式应用举例:工厂方法模式:创建药品对象
设计模式·工厂方法模式
代钦塔拉10 小时前
【C++/Qt 进阶】设计模式系列(5):适配器模式——给“不兼容的接口“贴一层翻译膜
c++·qt·设计模式
bigbread1 天前
策略模式 + 工厂方法模式在项目中的实战应用
设计模式
高晶1 天前
C 语言实现 BMS 系统中 SPI 通信协议实战指南
设计模式·程序员
代钦塔拉1 天前
【C++/Qt 进阶】设计模式系列(2):工厂模式——从游戏角色到披萨店
c++·算法·设计模式
高晶1 天前
2A3 单端甲类功放从零制作全攻略:电路设计、焊接调试到煲机维护一站式指南
前端·设计模式
代钦塔拉1 天前
【C++/Qt 进阶】设计模式系列(4):原型模式——用“克隆“代替“重新构造“
c++·qt·设计模式
博风1 天前
11、设计模式应用举例:迭代器模式:使用多个集合存储对象
设计模式·迭代器模式
日和雫2 天前
面向对象与面向过程,谁才是“银弹”?
设计模式