作者:俊铭心怡雅琪 | 来源:互联网 | 2023-10-09 22:08
作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
一、工厂模式是什么?
工厂模式是一种创建型的软件设计模式。定义一个用于创建对象的工厂接口,并让工厂子类决定实例化哪一个产品类,使产品类的实例化延迟到工厂子类中执行。说白了就是用来造东西的,一般是比较简单的东西,我们不需要知道它如何生产的,直接从工厂拿到产品即可。
工厂模式的优点:
- 良好的封装性。将产品的实例化封装执行,避免被修改,这样的产品具备良好的一致性。
- 良好的扩展性。增加产品时,同步增加一个工厂子类,不会违反开闭原则。
- 标准的解耦合框架。使用者只需要知道自己要什么产品即可,不用去管产品具体的特性等等,降低了模块间的耦合。
工厂模式的缺点:
- 代码量大。每加一个产品,都要加一个工厂子类,代码会显得臃肿。
- 不利于扩展复杂的产品结构。如果你要苹果、香蕉、梨,工厂模式的结构还可以,但如果你要山东的苹果、海南的香蕉、北京的苹果,就显得结构呆呆的。这可以用抽象工厂模式解决,对产品族和产品种类进行区分。
二、简单工厂模式
在介绍工厂模式前,先介绍其前身-简单工厂模式,简单工厂模式是用一个简单的工厂类,直接对产品进行实例化,虽然大大减少了代码量,但是违反了设计中的开闭原则,因为每次添加产品,工厂类都要进行修改。
2.1 结构图
客户端即Main主函数,调用简单工厂制造产品,并获取产品。具体要什么产品由客户端命令决定。
2.2 代码示例
场景描述:我联系了一个生产水果的工厂,从工厂拿了一个苹果、一个香蕉和一个梨,用来果腹,工厂给我一个报价我付钱即可。
//Prodect.h
/****************************************************/
#pragma once
#include
using namespace std;
// 产品种类
enum PRODECT_TYPE
{
APPLE, // 苹果
BANANA, // 香蕉
PEAR // 梨
};
// 抽象产品类
class Prodect
{
public:
// 构造函数
Prodect(int price) :m_price(price) {};
// 析构函数
virtual ~Prodect() {};
// 获取价格
int getPrice() {
return m_price;
}
protected:
// 产品价格
int m_price;
};
// 具体产品类-苹果
class AppleProdect : public Prodect
{
public:
// 构造函数
AppleProdect(int price) :Prodect(price) {
cout <<"获得了一个苹果。" < };
// 析构函数
virtual ~AppleProdect() {
cout <<"吃掉了一个苹果。" < };
};
// 具体产品类-香蕉
class BananaProdect : public Prodect
{
public:
// 构造函数
BananaProdect(int price) :Prodect(price) {
cout <<"获得了一个香蕉。" < };
// 析构函数
virtual ~BananaProdect() {
cout <<"吃掉了一个香蕉。" < };
};
// 具体产品类-梨
class PearProdect : public Prodect
{
public:
// 构造函数
PearProdect(int price) :Prodect(price) {
cout <<"获得了一个梨。" < };
// 析构函数
virtual ~PearProdect() {
cout <<"吃掉了一个梨。" < };
};
//Factory.h
/****************************************************/
#pragma once
#include
#include "Prodect.h"
using namespace std;
// 简单工厂
class SimpleFactory
{
public:
// 获取产品
Prodect* getProdect(PRODECT_TYPE type) {
Prodect* prodect &#61; nullptr;
switch (type)
{
case APPLE:
prodect &#61; new AppleProdect(5);
break;
case BANANA:
prodect &#61; new BananaProdect(2);
break;
case PEAR:
prodect &#61; new PearProdect(3);
break;
default:
cout <<"无该产品。" < break;
}
return prodect;
}
};
//main.cpp
/****************************************************/
#include
#include "Factory.h"
#include "Prodect.h"
using namespace std;
int main()
{
SimpleFactory* factory &#61; new SimpleFactory();
cout <<"开始生产。" < Prodect *A &#61; factory->getProdect(APPLE);
Prodect *B &#61; factory->getProdect(BANANA);
Prodect *C &#61; factory->getProdect(PEAR);
int applePrice &#61; A->getPrice();
int bananaPrice &#61; B->getPrice();
int pearPrice &#61; C->getPrice();
int sum &#61; A->getPrice() &#43; B->getPrice() &#43; C->getPrice();
cout <<"苹果价格&#xff1a;" < cout <<"香蕉价格&#xff1a;" < cout <<"梨子价格&#xff1a;" < cout <<"累计消费&#xff1a;" < delete A;
delete B;
delete C;
cout <<"享用完毕。" < return 0;
}
程序结果如下。
在上述示例中&#xff0c;我们可以看到&#xff0c;如果我想给工厂再添加一个产品&#xff0c;那么除了添加一个产品子类外&#xff0c;还要跑到简单工厂的类中进行switch的扩展&#xff0c;这样不利于代码的封装&#xff0c;破坏了开闭原则。而工厂模式的设计能弥补该不足。
三、工厂模式
3.1 结构图
客户端即Main主函数&#xff0c;通过工厂子类来制造对应的产品&#xff0c;并获取产品。具体要什么产品由工厂子类决定。
3.2 代码示例
场景描述&#xff1a;我联系了一个生产水果的工厂&#xff0c;从工厂拿了一个苹果、一个香蕉和一个梨&#xff0c;用来果腹&#xff0c;工厂给我一个报价我付钱即可。
//Prodect.h
/****************************************************/
#pragma once
#include
using namespace std;
// 抽象产品类
class Prodect
{
public:
// 构造函数
Prodect(int price) :m_price(price) {};
// 析构函数
virtual ~Prodect() {};
// 获取价格
int getPrice() {
return m_price;
}
protected:
// 产品价格
int m_price;
};
// 具体产品类-苹果
class AppleProdect : public Prodect
{
public:
// 构造函数
AppleProdect(int price) :Prodect(price) {
cout <<"获得了一个苹果。" < };
// 析构函数
virtual ~AppleProdect() {
cout <<"吃掉了一个苹果。" < };
};
// 具体产品类-香蕉
class BananaProdect : public Prodect
{
public:
// 构造函数
BananaProdect(int price) :Prodect(price) {
cout <<"获得了一个香蕉。" < };
// 析构函数
virtual ~BananaProdect() {
cout <<"吃掉了一个香蕉。" < };
};
// 具体产品类-梨
class PearProdect : public Prodect
{
public:
// 构造函数
PearProdect(int price) :Prodect(price) {
cout <<"获得了一个梨。" < };
// 析构函数
virtual ~PearProdect() {
cout <<"吃掉了一个梨。" < };
};
//Factory.h
/****************************************************/
#pragma once
#include
#include "Prodect.h"
using namespace std;
// 抽象工厂类
class Factory
{
public:
// 获取产品
virtual Prodect* getProdect() &#61; 0;
};
// 具体工厂类-苹果
class AppleFactory : public Factory
{
public:
// 获取产品
virtual Prodect* getProdect() {
Prodect* prodect &#61; new AppleProdect(5);
return prodect;
}
};
// 具体工厂类-香蕉
class BananaFactory : public Factory
{
public:
// 获取产品
virtual Prodect* getProdect() {
Prodect* prodect &#61; new BananaProdect(2);
return prodect;
}
};
// 具体工厂类-梨
class PearFactory : public Factory
{
public:
// 获取产品
virtual Prodect* getProdect() {
Prodect* prodect &#61; new PearProdect(3);
return prodect;
}
};
//main.cpp
/****************************************************/
#include
#include "Factory.h"
#include "Prodect.h"
using namespace std;
int main()
{
Factory* factoryA &#61; new AppleFactory();
Factory* factoryB &#61; new BananaFactory();
Factory* factoryC &#61; new PearFactory();
cout <<"开始生产。" < Prodect *A &#61; factoryA->getProdect();
Prodect *B &#61; factoryB->getProdect();
Prodect *C &#61; factoryC->getProdect();
int applePrice &#61; A->getPrice();
int bananaPrice &#61; B->getPrice();
int pearPrice &#61; C->getPrice();
int sum &#61; A->getPrice() &#43; B->getPrice() &#43; C->getPrice();
cout <<"苹果价格&#xff1a;" < cout <<"香蕉价格&#xff1a;" < cout <<"梨子价格&#xff1a;" < cout <<"累计消费&#xff1a;" < delete A;
delete B;
delete C;
cout <<"享用完毕。" < return 0;
}
程序结果如下。
这样设计的好处就是如果多一个产品&#xff0c;那就只需要在产品类和工厂类中各扩展一个子类即可&#xff0c;不影响原有的程序。
四、总结
我尽可能用较通俗的话语和直观的代码例程&#xff0c;来表述我对工厂模式的理解&#xff0c;或许有考虑不周到的地方&#xff0c;如果你有不同看法欢迎评论区交流&#xff01;希望我举的例子能帮助你更好地理解工厂模式。
如果文章帮助到你了&#xff0c;可以点个赞让我知道&#xff0c;我会很快乐~加油&#xff01;