工程地址:设计模式-简单工厂源码-C++文档类资源-CSDN下载C++设计模式-创建型模式-简单工厂模式源码更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/qq_40788199/85538774
码云地址:https://gitee.com/gongguixing/c-design-mode.githttps://gitee.com/gongguixing/c-design-mode.git
1、定义
工厂模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。
按实际业务场景划分,工厂模式有 3 种不同的实现方式,分别是简单工厂模式、工厂方法模式和抽象工厂模式。
我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”。
在简单工厂模式中创建实例的方法通常为静态(static)方法,因此简单工厂模式(Simple Factory Pattern)又叫作静态工厂方法模式(Static Factory Method Pattern)。
简单来说,简单工厂模式有一个具体的工厂类,可以生成多个不同的产品,属于创建型设计模式。简单工厂模式不在 GoF 23 种设计模式之列。
简单工厂模式每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度,违背了“开闭原则”。
2、优点和缺点
优点:
-
工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责,很方便的创建出相应的产品。工厂和产品的职责区分明确。
-
客户端无需知道所创建具体产品的类名,只需知道参数即可。
-
也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。
缺点:
-
简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高聚合原则。
-
使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
-
系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
-
简单工厂模式使用了 static 工厂方法,造成工厂角色无法形成基于继承的等级结构。
3、应用场景
对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。
4、模式的结构与实现
简单工厂模式的主要角色如下:
- 简单工厂(SimpleFactory):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
- 抽象产品(Product):是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
- 具体产品(ConcreteProduct):是简单工厂模式的创建目标。
工厂代码:
#ifndef CSIMPLEFACTORY_H
#define CSIMPLEFACTORY_H
#include "ifruit.h"
#include "string"
using namespace std;
class CSimpleFactory
{
public:
CSimpleFactory();
// 生产水果接口
static IFruit * makeFruit(const string &name);
};
#endif // CSIMPLEFACTORY_H
#include "csimplefactory.h"
#include "apple.h"
#include "banana.h"
#include "pear.h"
CSimpleFactory::CSimpleFactory()
{
}
IFruit *CSimpleFactory::makeFruit(const string &name)
{
// 根据传入参数name生产水果
if (name.compare("apple") == 0)
{
// 生产苹果
return new Apple();
}
else if (name.compare("banana") == 0)
{
// 生产香蕉
return new Banana();
}
else if (name.compare("pear") == 0)
{
// 生产梨子
return new Pear();
}
return NULL;
}
水果接口类代码:
#ifndef IFRUIT_H
#define IFRUIT_H
// 水果基类
class IFruit
{
public:
// 虚析构函数,动态绑定,方便在外部释放对象
virtual ~IFruit() {}
// 显示名称
virtual void show() = 0;
};
#endif // IFRUIT_H
产品苹果类代码:
#ifndef APPLE_H
#define APPLE_H
#include "ifruit.h"
// 继承于水果基类
class Apple : public IFruit
{
public:
Apple();
// 重写show方法
void show() override;
};
#endif // APPLE_H
#include "apple.h"
#include "iostream"
Apple::Apple()
{
}
void Apple::show()
{
std::cout << "I am an apple!" << std::endl;
}
产品香蕉类代码:
#ifndef BANANA_H
#define BANANA_H
#include "ifruit.h"
class Banana : public IFruit
{
public:
Banana();
// 重写show方法
void show() override;
};
#endif // BANANA_H
#include "banana.h"
#include "iostream"
Banana::Banana()
{
}
void Banana::show()
{
std::cout << "I am a banana!" << std::endl;
}
产品梨子类代码:
#ifndef PEAR_H
#define PEAR_H
#include "ifruit.h"
class Pear : public IFruit
{
public:
Pear();
// 重写show方法
void show() override;
};
#endif // PEAR_H
#include "pear.h"
#include "iostream"
Pear::Pear()
{
}
void Pear::show()
{
std::cout << "I am a pear!" << std::endl;
}
调用代码:
#include <iostream>
#include "csimplefactory.h"
int main()
{
// 告诉工厂生产苹果
IFruit *a = CSimpleFactory::makeFruit("apple");
a->show();
// 告诉工厂生产香蕉
IFruit *b = CSimpleFactory::makeFruit("banana");
b->show();
// 告诉工厂生产梨子
IFruit *c = CSimpleFactory::makeFruit("pear");
c->show();
// 创建了对象记得释放,delete
return 0;
}