文章目录
- 一、简单工厂
- 1.1、原理
- 1.2、核心角色
- 1.3、UML类图
- 1.4、代码实现
- 1.5、总结
- 二、工厂模式
- 2.1、原理
- 2.2、关键角色
- 2.3、代码实现
- 2.4、总结
- 三、抽象工厂模式
- 3.1、原理
- 3.2、关键角色
- 3.3、UML类图
- 3.4、工厂模式与抽象工厂模式的区别
前言
工厂模式是最常用的设计模式之一,它提供了一种创建对象的最佳方式,在创建对象的时候,不会对客户端暴露创建逻辑,并且通过使用一个共同的接口来创建新的对象。工厂模式有三种,分别是简单工厂、工厂模式,抽象工厂。
一、简单工厂
1.1、原理
通过传⼊相关的类型来返回相应的类对象,简单工厂模式看为工厂方法模式的一种特例。
1.2、核心角色
- 简单工厂(SimpleFactory):根据类型创建类对象
- 抽象产品(IProduct):产品接口,描述所有实例对象的公共接口
- 具体产品(ConcreteProduct):实现产品接口
1.3、UML类图
下面以生成手机的代码为例,介绍简单工厂模式,UML类图如下:
1.4、代码实现
代码实现,如下:
#include <iostream>
using namespace std;
// 手机(抽象接口)
class IPhone {
public:
virtual void Describe() = 0;
};
// 华为手机(具体产品)
class HuaweiPhone : public IPhone {
public:
void Describe() {
cout << "华为手机" << endl;
}
};
// 苹果手机(具体产品)
class ApplePhone : public IPhone {
public:
void Describe() {
cout << "苹果手机" << endl;
}
};
// 简单工厂
class PhoneFactory {
public:
IPhone* Produce(string type) {
IPhone *pPhone = nullptr;
if (type == "Huawei") {
pPhone = new HuaweiPhone;
} else if (type == "Apple") {
pPhone = new ApplePhone;
}
return pPhone;
}
};
int main()
{
// 简单工厂
PhoneFactory factory;
IPhone *pHuaweiPhone = factory.Produce("Huawei");
IPhone *pApplePhone = factory.Produce("Apple");
pHuaweiPhone->Describe();
pApplePhone->Describe();
return 0;
}
1.5、总结
简单工厂模式优点与缺点,如下:
优点:
- 实现简单
- 实现了对象创建与业务逻辑的分离
缺点:
- 可扩展性差,如果新增手机产品,就需要修改
PhoneFactory::Produce
方法,违反了开放封闭原则
二、工厂模式
2.1、原理
定义创建对象抽象工厂,具体工厂负责实现抽象工厂接口,创建对应类型的对象
2.2、关键角色
- 抽象工厂:定义了创建抽象产品的抽象工厂
- 具体工厂:实现抽象工厂接口的具体工厂类,负责生产具体的产品
- 抽象产品:产品接口,描述所有实例对象的公共接口
- 具体产品:实现产品接口
2.3、代码实现
#include <iostream>
using namespace std;
// 手机(抽象接口)
class IPhone {
public:
virtual void Describe() = 0;
};
// 华为手机(具体产品)
class HuaweiPhone : public IPhone {
public:
void Describe() {
cout << "华为手机" << endl;
}
};
// 苹果手机(具体产品)
class ApplePhone : public IPhone {
public:
void Describe() {
cout << "苹果手机" << endl;
}
};
// 抽象工厂
class IFactory {
public:
virtual IPhone* Produce() = 0;
};
// 具体工厂(生产华为手机)
class HuaweiPhoneFactory : public IFactory {
public:
IPhone* Produce() {
return new HuaweiPhone;
}
};
// 具体工厂(生产苹果手机)
class ApplePhoneFactory : public IFactory {
public:
IPhone* Produce() {
return new ApplePhone;
}
};
int main()
{
// 工厂对象
HuaweiPhoneFactory huaweiFactory;
ApplePhoneFactory appleFactory;
IPhone *pHuaweiPhone = huaweiFactory.Produce();
IPhone *pApplePhone = appleFactory.Produce();
pHuaweiPhone->Describe();
pApplePhone->Describe();
return 0;
}
2.4、总结
工厂模式优点与缺点,如下:
优点:
- 解决了简单工厂模式可扩展性差的问题,如果新增手机产品,新增一个产品类及对应的工厂类就可以,不会修改原有的代码,符合开放封闭原则
缺点:
- 随着产品的增多,类的个数容易过多,增加复杂度
- 具体工厂只能生产出一种产品(可以用抽象工厂模式解决)
三、抽象工厂模式
3.1、原理
抽象工厂模式在工厂方法模式的基础上进行进一步抽象。设想下面这种场景:在手机的基础上新增了Pad,要创建
华为Phone
、华为Pad
、苹果Phone
、苹果Pad
等产品,如果使用工厂模式,就要新增四个工厂类,使用工厂方法模式,创建了很多具体工厂类,而没有利用产品的商品族的概念。
抽象工厂模式是用于解决一类产品的创建问题(在上述场景中,可以把
华为Phone
、华为Pad
、苹果Phone
、苹果Pad
归纳为Phone
,Pad
这两类商品)
3.2、关键角色
抽象工厂模式与工厂模式的关键角色类似,有差异的地方在于抽象工厂类,如下:
- 抽象工厂类:定义一组接口,用于创建多类产品;工厂方法的抽象工厂类,只定义了创建一类产品的接口
3.3、UML类图
使用抽象工厂类解决工厂方法遇到的两个问题,一是:只能生产一类产品的问题;二是:增加产品导致产品工厂类的个数容易过多的问题(解决新增
Pad
产品的问题,如果使用抽象工厂方法需要新增两个工厂类,而使用工厂方法需要四个工厂类),UML类图如下:
3.4、工厂模式与抽象工厂模式的区别
工厂模式主要解决一类产品的创建问题,抽象工厂模式主要是来解决多类(产品簇)产品创建问题。具体差异体现在抽象工厂角色上,工厂模式提供一个接口,创建一类产品;抽象工厂提供多个接口,可以创建多类产品。