- 1什么是工厂模式?
工厂模式,顾名思义,就是把将对象的实例化过程封装在工厂类中的方式。工厂负责生产相应的对象实例。
一般分为两种工厂模式:简单工厂;抽象工厂
优点:
- 用户不需要解决具体的细节问题,利用工厂类进行生产产品细节;
- 可以将对象的创建与使用代码分离,提供一种统一的接口来创建不同类型的对象。
- 创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
缺点:简单工厂;抽象工厂各有各自的优缺点(后面详细展开)
- 2简单工厂SimpleFactory
UML 类图分析:
1、抽象产品 (AbstractProduct)
2、产品的具体实现类(Product1 和 Product2)
3、工厂类 (Factory)
代码示例
头文件
抽象产品类Phone,提供虚函数接口
#ifndef _PHONE_HEAD_H
#define _PHONE_HEAD_H
class AbstractPhone
{
public:
AbstractPhone() { std::cout << "AbstractPhone的构造函数 " << std::endl; }
virtual ~AbstractPhone() { std::cout << "AbstractPhone的析构函数 " << std::endl; }
virtual void call() = 0;
virtual void message() = 0;
};
#endif
工厂类,提供父类指针指向函数接口,用来创建出相应的子类对象;
#ifndef _SIMPLE_FACTORY_HEAD_H
#define _SIMPLE_FACTORY_HEAD_H
#include"AndroidPhone.h"
#include"Iphone.h"
//#include<memory>
//工厂类,用于生产手机
class SimpleFactory
{
public:
SimpleFactory() {
std::cout << "SimpleFactory() call " << std::endl;
}
~SimpleFactory() {
std::cout << "~SimpleFactory() call " << std::endl;
}
//使用多态,父类指针指向函数接口,用来创建出相应的子类对象
static AbstractPhone* getPhone(const string &name ) {
if (name == "AndroidPhone") {
return new AndroidPhone;
}
else if (name == "Iphone") {
return new IPhone;
}
return nullptr;
}
};
#endif
具体产品类安卓手机类,继承抽象产品Phone类,并且使用多态
#ifndef _ANDROID_PHONE_HEAD_H
#define _ANDROID_PHONE_HEAD_H
#include"Phone.h"
#include<iostream>
using namespace std;
class AndroidPhone :public AbstractPhone
{
public:
AndroidPhone() {
cout << "AndroidPhone构造函数 " << endl;
}
~AndroidPhone() {
cout << "~AndroidPhone析构函数 " << endl;
}
void call() override {
cout << "AndroidPhone call " << endl;
}
void message() override {
cout << "AndroidPhone message " << endl;
}
};
#endif // !_ANDROID_PHONE_HEAD_H
具体产品类Iphone类,继承抽象产品Phone类,并且使用多态
#ifndef _ANDROID_PHONE_HEAD_H
#define _ANDROID_PHONE_HEAD_H
#include"Phone.h"
#include<iostream>
using namespace std;
class AndroidPhone :public AbstractPhone
{
public:
AndroidPhone() {
cout << "AndroidPhone构造函数 " << endl;
}
~AndroidPhone() {
cout << "~AndroidPhone析构函数 " << endl;
}
void call() override {
cout << "AndroidPhone call " << endl;
}
void message() override {
cout << "AndroidPhone message " << endl;
}
};
#endif // !_ANDROID_PHONE_HEAD_H
main.cpp文件
#include<iostream>
#include"SimpleFactory.h"
using namespace std;
//mian函数中只需要向工厂要手机即可
int main()
{
AbstractPhone* androidPhone = SimpleFactory::getPhone("AndroidPhone");
AbstractPhone* iPhone = SimpleFactory::getPhone("Iphone");
androidPhone->call();
androidPhone->message();
cout << "----------------------" << endl;
iPhone->call();
iPhone->message();
return 0;
}
简单分析一下simple factory模式缺点
阅读上述代码不难发现,具体的产品都是通过这个函数来实例化的
static AbstractPhone* getPhone(const string &name )
而如果有新的需求,生产新产品锤子手机,就需要在该函数中修改添加相应代码;而如果需要有很多的新的需求呢,或者变更了需求呢,修改就随之变得非常繁琐;
在面向对象开发中有一个很重要的原则︰
开闭原则概念(程序扩展是开放的,程序修改是封闭的,扩展优于修改),在新增产品时,很明显的,我们要修改原有的工厂代码,违背了开闭原则。
- 3.抽象工厂AbstructFactory模式
引入抽象工厂模式时,不能说这个模式就一定高大上,主要还是看使用场景与工厂方法模式相比;
抽象 工厂模式主要是打破了工厂与产品一对一,使得具体工厂可以创造一个大类产品 (一系列产品)
UML 类图分析:
- 引入了新的产品维度 (产品 A\B),即在原本的产品维度(1\2)基础上加上了产品维度(AB)
- 创建两个大类产品接口 AbstractProductA 和 AbstractProductB
- 编写产品的具体实现类: ProductA1、ProductA2、ProductB1,ProductB2
- 针对大类产品接口,编写大类工厂接口 AbstractFactory
- 编写俩个大类工厂类: ConcreteFactory1、 ConcreteFactory2
代码演示
//抽象父类按钮产品接口
class Button
{
public:
Button()
{
cout << "父类Button的构造函数" << endl;
}
virtual ~Button()
{
cout << "父类Button的析构函数" << endl;
}
//抽象的产品接口render(),纯虚函数
virtual void render() = 0;
};
//抽象工厂接口
class AbstructFactory
{
public:
AbstructFactory()
{
cout << "父类AbstructFactory的构造函数 " << endl;
}
virtual ~AbstructFactory()
{
cout << "父类AbstructFactory的析构函数 " << endl;
}
//Button类指针指向一个纯虚函数,用于创建产品
virtual Button* createButton() = 0;
};
//具体生产某一类Android产品的工厂,继承抽象工厂的接口
class AndroidFactory:public AbstructFactory
{
public:
AndroidFactory()
{
cout << "AndroidFactory工厂的构造函数 " << endl;
}
~AndroidFactory()
{
cout << "AndroidFactory工厂的析构函数 " << endl;
}
Button* createButton() override {
return new AndroidButton;
}
};
//具体生产某一类IphoneFactory产品的工厂,继承抽象工厂的接口
class IphoneFactory :public AbstructFactory
{
public:
IphoneFactory()
{
cout << "Iphone工厂的构造函数 " << endl;
}
~IphoneFactory()
{
cout << "Iphone工厂的析构函数 " << endl;
}
Button* createButton() override {
return new IphoneButton;
}
};
main.cpp
int main()
{
AbstractPhone* androidPhone = SimpleFactory::getPhone("AndroidPhone");
AbstractPhone* iPhone = SimpleFactory::getPhone("Iphone");
androidPhone->call();
androidPhone->message();
cout << "----------------------" << endl;
iPhone->call();
iPhone->message();
return 0;
}
不难发现 抽象工厂的设计思路与简单工厂不同:
- 抽象工厂不仅提供了 抽象的工厂泛类 还提供了 产品的泛类
- 具体工厂继承抽象工厂,具体产品继承抽象产品;并都使用多态
那么这样做的好处:
- 抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么产品的创建过程。
- 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
- 增加新的具体工厂和产品族很方便,无须修改已有系统,符合 “开闭原则”。
感谢看到这里,
下篇我将分析一下工厂模式中的一些细节问题,以及在程序设计的时候需要注意的问题
敬请期待后续更新中.....