重拾设计模式--工厂模式(简单、工厂、抽象)

文章目录

工厂模式定义

工厂模式(Factory Pattern)属于创建型设计模式,它主要用于对象的创建过程,将对象的创建和使用分离,把对象创建的逻辑封装在工厂类中,这样当需要创建对象时,不用在客户端代码里直接通过 new 操作符等去实例化对象,而是通过调用工厂类的相应方法来获取对象。这使得代码的维护性和可扩展性更好,也提高了代码的灵活性和可复用性。

工厂模式通常可以细分为以下几种类型

1、简单工厂模式(Simple Factory Pattern)

它是工厂模式的基础,虽然严格来说不算 GoF(Gang of Four,设计模式四人组)提出的 23 种设计模式之一,但却是理解工厂模式的重要起点。简单工厂模式有一个工厂类,该工厂类根据传入的参数等条件来决定创建哪种具体产品对象。

2、工厂方法模式(Factory Method Pattern)

在简单工厂模式上进行了改进,把具体产品对象的创建方法延迟到具体的工厂子类中实现,工厂类变成抽象类,有一个抽象的创建方法,每个具体的工厂子类负责创建对应的具体产品对象,符合开闭原则(对扩展开放,对修改关闭)。

3、抽象工厂模式(Abstract Factory Pattern)

更为复杂和抽象,工厂类负责创建一系列相关的产品对象,客户端调用抽象工厂类的抽象创建方法,由具体的工厂子类来创建符合特定需求的一组相关产品,常用于创建一组有内在关联、需要统一创建的对象场景。

UML 图

1、简单工厂模式UML

2、工厂模式UML

3、抽象工厂模式UML

C++ 代码示例。

1、简单工厂模式

结构及原理

简单工厂模式包含以下几个关键部分:

抽象产品(Product):定义产品对象的接口,描述了产品共有的行为和属性。

具体产品(ConcreteProduct):实现抽象产品接口,代表具体的产品对象,不同的具体产品有其独特的实现逻辑。

工厂类(Factory):负责创建具体的产品对象,根据传入的条件或者参数决定实例化哪种具体产品。

C++ 代码示例

cpp 复制代码
#include <iostream>
#include <string>

// 抽象产品
class Product
{
public:
	virtual void use() = 0;
	virtual ~Product() {}
};

// 具体产品A
class ConcreteProductA : public Product 
{
public:
	void use() override {
		std::cout << "Using ConcreteProductA" << std::endl;
	}
};

// 具体产品B
class ConcreteProductB : public Product
{
public:
	void use() override
	{
		std::cout << "Using ConcreteProductB" << std::endl;
	}
};

// 工厂类
class Factory
{
public:
	static Product* createProduct(const std::string& type)
	{
		if (type == "A")
		{
			return new ConcreteProductA();
		}
		else if (type == "B")
		{
			return new ConcreteProductB();
		}
		return nullptr;
	}
};

int main()
{
	Product* productA = Factory::createProduct("A");
	Product* productB = Factory::createProduct("B");

	if (productA)
	{
		productA->use();
		delete productA;
	}

	if (productB)
	{
		productB->use();
		delete productB;
	}
	char t;
	std::cin>>t;
	return 0;
}

在上述代码中:

Product 是抽象产品类,定义了 use 这个抽象方法,代表产品被使用时的操作。

ConcreteProductA 和 ConcreteProductB 是具体产品类,分别实现了 use 方法,有着各自不同的使用逻辑。

Factory 是工厂类,其 createProduct 静态方法根据传入的产品类型字符串来决定创建哪种具体产品对象,然后返回给客户端使用。在 main 函数中,通过工厂类创建了不同的产品对象并调用它们的 use 方法展示功能,最后记得释放内存,避免内存泄漏。

工厂方法模式

结构及原理

工厂方法模式在简单工厂模式基础上做了如下改变:

抽象工厂(Abstract Factory):作为工厂类的抽象,定义了抽象的创建产品的方法,具体的创建逻辑延迟到具体工厂子类中。

具体工厂(Concrete Factory):继承自抽象工厂,实现抽象的创建方法,负责创建对应的具体产品对象。

在简单工厂模式的基础上,把对象的创建分布在各个产品对应的工厂内,而不是在一个工厂内,更加符合开闭原则,简单工厂模式严格来说不符合开闭原则,因为他对修改还是开放的

C++ 代码示例

cpp 复制代码
#include <iostream>
#include <string>

// 抽象产品
class Product 
{
public:
	virtual void use() = 0;
	virtual ~Product() {}
};

// 具体产品A
class ConcreteProductA : public Product 
{
public:
	void use() override
	{
		std::cout << "Using ConcreteProductA" << std::endl;
	}
};

// 具体产品B
class ConcreteProductB : public Product 
{
public:
	void use() override 
	{
		std::cout << "Using ConcreteProductB" << std::endl;
	}
};

// 抽象工厂
class AbstractFactory
{
public:
	virtual Product* createProduct() = 0;
	virtual ~AbstractFactory() {}
};

// 具体工厂A,负责创建产品A
class ConcreteFactoryA : public AbstractFactory
{
public:
	Product* createProduct() override
	{
		return new ConcreteProductA();
	}
};

// 具体工厂B,负责创建产品B
class ConcreteFactoryB : public AbstractFactory
{
public:
	Product* createProduct() override
	{
		return new ConcreteProductB();
	}
};

int main()
{
	AbstractFactory* factoryA = new ConcreteFactoryA();
	AbstractFactory* factoryB = new ConcreteFactoryB();

	Product* productA = factoryA->createProduct();
	Product* productB = factoryB->createProduct();

	if (productA) 
	{
		productA->use();
		delete productA;
	}

	if (productB)
	{
		productB->use();
		delete productB;
	}

	delete factoryA;
	delete factoryB;

	return 0;
}

在这个代码中:

AbstractFactory 抽象工厂类定义了抽象的 createProduct 方法,让具体工厂子类去实现具体的创建逻辑。

ConcreteFactoryA 和 ConcreteFactoryB 分别是负责创建不同具体产品的具体工厂类,它们重写了 createProduct 方法来实例化对应的产品。在 main 函数中,先创建具体的工厂对象,再通过工厂对象创建相应的产品对象并使用,最后按顺序释放工厂对象和产品对象的内存,保证内存管理的正确性。

抽象工厂模式

结构及原理

抽象工厂模式的核心在于创建一系列相关的产品对象,其结构特点如下:

抽象工厂(Abstract Factory):定义了创建一系列相关产品的抽象方法,例如创建产品 A、产品 B 等多个抽象方法(在更复杂场景中可能更多)。

具体工厂(Concrete Factory):实现抽象工厂接口,负责创建一组特定的相关产品对象,满足特定的业务需求组合。

抽象产品族(Abstract Product Family):包含多个抽象产品类,这些抽象产品类通常在业务上是相关联的,一起构成了产品族的抽象定义。

具体产品(Concrete Product):实现抽象产品族中的相应抽象产品类,代表具体的产品对象,不同的具体工厂创建不同组合的具体产品。

C++ 代码示例

下面以一个简单的游戏开发中创建不同主题风格的游戏角色和武器为例(比如有魔幻主题和科幻主题):

cpp 复制代码
#include <iostream>
#include <string>

// 抽象产品:游戏角色
class Character
{
public:
	virtual void show() = 0;
	virtual ~Character() {}
};

// 抽象产品:游戏武器
class Weapon
{
public:
	virtual void attack() = 0;
	virtual ~Weapon() {}
};

// 具体产品:魔幻角色
class MagicCharacter : public Character 
{
public:
	void show() override
	{
		std::cout << "A magic character appears." << std::endl;
	}
};

// 具体产品:魔幻武器
class MagicWeapon : public Weapon
{
public:
	void attack() override 
	{
		std::cout << "Magic weapon attacks with spells." << std::endl;
	}
};

// 具体产品:科幻角色
class SciFiCharacter : public Character 
{
public:
	void show() override
	{
		std::cout << "A sci-fi character appears." << std::endl;
	}
};

// 具体产品:科幻武器
class SciFiWeapon : public Weapon
{
public:
	void attack() override 
	{
		std::cout << "Sci-fi weapon attacks with energy beams." << std::endl;
	}
};

// 抽象工厂
class AbstractFactory
{
public:
	virtual Character* createCharacter() = 0;
	virtual Weapon* createWeapon() = 0;
	virtual ~AbstractFactory() {}
};

// 具体工厂:魔幻主题工厂
class MagicFactory : public AbstractFactory
{
public:
	Character* createCharacter() override
	{
		return new MagicCharacter();
	}
	Weapon* createWeapon() override
	{
		return new MagicWeapon();
	}
};

// 具体工厂:科幻主题工厂
class SciFiFactory : public AbstractFactory 
{
public:
	Character* createCharacter() override
	{
		return new SciFiCharacter();
	}
	Weapon* createWeapon() override 
	{
		return new SciFiWeapon();
	}
};


int main()
{
	AbstractFactory* magicFactory = new MagicFactory();
	AbstractFactory* sciFiFactory = new SciFiFactory();

	// 创建魔幻主题的角色和武器
	Character* magicCharacter = magicFactory->createCharacter();
	Weapon* magicWeapon = magicFactory->createWeapon();

	// 创建科幻主题的角色和武器
	Character* sciFiCharacter = sciFiFactory->createCharacter();
	Weapon* sciFiWeapon = sciFiFactory->createWeapon();

	if (magicCharacter) 
	{
		magicCharacter->show();
		delete magicCharacter;
	}

	if (magicWeapon)
	{
		magicWeapon->attack();
		delete magicWeapon;
	}

	if (sciFiCharacter)
	{
		sciFiCharacter->show();
		delete sciFiCharacter;
	}

	if (sciFiWeapon)
	{
		sciFiWeapon->attack();
		delete sciFiWeapon;
	}

	delete magicFactory;
	delete sciFiFactory;

	char t;
	std::cin>>t;

	return 0;
}

在这个示例中:

Character 和 Weapon 分别是抽象的游戏角色和武器产品类,定义了各自展示和攻击的抽象方法。

MagicCharacter、MagicWeapon、SciFiCharacter、SciFiWeapon 是对应的具体产品类,实现了各自的具体行为逻辑。

AbstractFactory 是抽象工厂类,定义了创建角色和武器的抽象方法。

MagicFactory 和 SciFiFactory 是具体工厂类,分别负责创建魔幻主题和科幻主题的角色和武器这一组相关产品。在 main 函数中,通过不同的具体工厂创建相应主题的产品并调用其方法展示功能,最后正确释放所有创建对象所占用的内存。

总结

简单工厂模式、工厂模式、抽象工厂模式是逐渐递进,

1、简单工厂模式是在一个工厂内生产多个产品;

2、工厂模式是一个工厂生产一个产品;

3、抽象工厂模式是一个工厂生产多个产品。

相关推荐
无 证明2 小时前
new 分配空间;引用
数据结构·c++
Damon_X3 小时前
桥接模式(Bridge Pattern)
设计模式·桥接模式
别NULL6 小时前
机试题——疯长的草
数据结构·c++·算法
CYBEREXP20087 小时前
MacOS M3源代码编译Qt6.8.1
c++·qt·macos
yuanbenshidiaos8 小时前
c++------------------函数
开发语言·c++
越甲八千8 小时前
重温设计模式--享元模式
设计模式·享元模式
yuanbenshidiaos8 小时前
C++----------函数的调用机制
java·c++·算法
tianmu_sama8 小时前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
羚羊角uou8 小时前
【C++】优先级队列以及仿函数
开发语言·c++
姚先生978 小时前
LeetCode 54. 螺旋矩阵 (C++实现)
c++·leetcode·矩阵