本文通过一个例子简单介绍简单工厂模式、工厂模式和抽象工厂模式。
假如我想换个手机,换什么手机呢?可以考虑苹果或者华为手机,那我们用简单工厂模式来实现这个功能:
我们关注的产品是手机,那生产手机的工厂有苹果,有华为,用户也不确定选哪种怎么办?这里用简单工厂模式:定义两个枚举类型,然后写一个工厂类,根据用户传入的枚举类型生产对应品牌的手机:
手机基类:
#pragma once
class MyPhone
{
public:
MyPhone(double price);
~MyPhone();
double getPrice() { return m_price; }
private:
double m_price;
};
#include "MyPhone.h"
MyPhone::MyPhone(double price) :m_price(price)
{
}
MyPhone::~MyPhone()
{
}
苹果手机:
#pragma once
#include "MyPhone.h"
class Phone_Apple:public MyPhone
{
public:
Phone_Apple(double price);
~Phone_Apple();
};
#include "Phone_Apple.h"
#include "stdio.h"
Phone_Apple::Phone_Apple(double price):MyPhone(price)
{
printf("This is iPhone!");
}
Phone_Apple::~Phone_Apple()
{
}
华为手机:
#pragma once
#include "MyPhone.h"
class Phone_Huawei :public MyPhone
{
public:
Phone_Huawei(double price);
~Phone_Huawei();
};
#include "Phone_Huawei.h"
#include "stdio.h"
Phone_Huawei::Phone_Huawei(double price) :MyPhone(price)
{
printf("This is HUAWEI!");
}
Phone_Huawei::~Phone_Huawei()
{
}
简单工厂类:
#pragma once
#include "MyPhone.h"
enum phoneType
{
APPLE_Phone,
HUAWEI_Phone
};
class SimpleFactory
{
public:
SimpleFactory();
~SimpleFactory();
MyPhone* createPhone(phoneType type);
};
#include "SimpleFactory.h"
#include "Phone_Apple.h"
#include "Phone_Huawei.h"
SimpleFactory::SimpleFactory()
{
}
SimpleFactory::~SimpleFactory()
{
}
MyPhone* SimpleFactory::createPhone(phoneType type)
{
MyPhone* phone = nullptr;
switch (type)
{
case APPLE_Phone:
phone = new Phone_Apple(6000);
break;
case HUAWEI_Phone:
phone = new Phone_Huawei(5600);
break;
}
return phone;
}
用户根据自定义类型修改创建:
SimpleFactory* factory = new SimpleFactory();
//用户指定要苹果
MyPhone* phone = factory->createPhone(APPLE_Phone);
cout << "Price: " << phone->getPrice() << endl;
delete phone;
delete factory;
这里的工厂类似于一个手机销售店,你需要什么手机就提供什么手机,没有问题,如果用户增加了需求,想要添加三星、OPPO等,怎么办?
很明显每次都要对原文件修改,如何避免呢?这里进入工厂模式:将生产手机的工厂抽象出来,然后将具体的生产厂家继承自这个抽象工厂,分别创建自己的产品:
抽象工厂类:
#pragma once
#include "MyPhone.h"
class IFactory
{
public:
IFactory();
~IFactory();
virtual MyPhone* createPhone() = 0;
};
华为工厂:
#pragma once
#include "IFactory.h"
#include "MyPhone.h"
class HuaweiFactory : public IFactory
{
public:
HuaweiFactory();
~HuaweiFactory();
virtual MyPhone* createPhone();
};
#include "HuaweiFactory.h"
#include "Phone_Huawei.h"
HuaweiFactory::HuaweiFactory()
{
}
HuaweiFactory::~HuaweiFactory()
{
}
MyPhone* HuaweiFactory::createPhone()
{
MyPhone* phone = new Phone_Huawei(5600);
return phone;
}
苹果工厂:
#pragma once
#include "IFactory.h"
#include "MyPhone.h"
class IphoneFactory : public IFactory
{
public:
IphoneFactory();
~IphoneFactory();
virtual MyPhone* createPhone();
};
#include "IphoneFactory.h"
#include "Phone_Apple.h"
IphoneFactory::IphoneFactory()
{
}
IphoneFactory::~IphoneFactory()
{
}
MyPhone* IphoneFactory::createPhone()
{
MyPhone* phone = new Phone_Apple(6000);
return phone;
}
//3.2 工厂模式
IFactory* factory = new IphoneFactory();
MyPhone* phone = factory->createPhone();
cout << "Price: " << phone->getPrice() << endl;
IFactory* factory1 = new HuaweiFactory();
MyPhone* phone1 = factory1->createPhone();
cout << "Price: " << phone1->getPrice() << endl;
delete phone;
delete phone1;
delete factory;
delete factory1;
这时,如果用户需要增加产品类型,比如华为的平板、苹果的平板怎么办?这就要引入抽象工厂模式了。
在原来代码基础上进行修改:
产品抽象类:
#pragma once
class MyPhone
{
public:
MyPhone(double price);
~MyPhone();
double getPrice() { return m_price; }
private:
double m_price;
};
class MyPad
{
public:
MyPad(double price);
~MyPad();
double getPrice() { return m_price; }
private:
double m_price;
};
苹果产品类:
#pragma once
#include "MyPhone.h"
class Phone_Apple:public MyPhone
{
public:
Phone_Apple(double price);
~Phone_Apple();
};
class Pad_Apple :public MyPad
{
public:
Pad_Apple(double price);
~Pad_Apple();
};
华为产品类:
#pragma once
#include "MyPhone.h"
class Phone_Huawei :public MyPhone
{
public:
Phone_Huawei(double price);
~Phone_Huawei();
};
class Pad_Huawei :public MyPad
{
public:
Pad_Huawei(double price);
~Pad_Huawei();
};
抽象工厂类:
#pragma once
#include "MyPhone.h"
class IFactory
{
public:
IFactory();
~IFactory();
virtual MyPhone* createPhone() = 0;
virtual MyPad* createPad() = 0;
}
具体工厂类:
#pragma once
#include "IFactory.h"
#include "MyPhone.h"
#include "Phone_Apple.h"
class IphoneFactory : public IFactory
{
public:
IphoneFactory();
~IphoneFactory();
virtual MyPhone* createPhone(){
MyPhone* phone = new Phone_Apple(6000);
return phone;
}
virtual MyPad* createPad() {
MyPad* phone = new Pad_Apple(4900);
return phone;
}
};
#pragma once
#include "IFactory.h"
#include "MyPhone.h"
#include "Phone_Huawei.h"
class HuaweiFactory : public IFactory
{
public:
HuaweiFactory();
~HuaweiFactory();
virtual MyPhone* createPhone() {
MyPhone* phone = new Phone_Huawei(5600);
return phone;
}
virtual MyPad* createPad() {
MyPad* phone = new Pad_Huawei(4600);
return phone;
}
};
调用:
//3.3 抽象工厂模式
IFactory* factory = new HuaweiFactory();
MyPad* pad = factory->createPad();
cout << "Price: " << pad->getPrice() << endl;
MyPhone* phone = factory->createPhone();
cout << "Price: " << phone->getPrice() << endl;
delete pad;
delete phone;
delete factory;
分别理解三种模式并不困难,关键就在于根据实际问题实际情况选用不同的模式,先总结如下思考方式,供参考:
总之要尽量满足OOP七大原则:
简单(静态)工厂模式:
用来生产同一等级结构中的任意产品(对于增加新的产品,需要修改已有代码;
工厂方法模式:
用来生产同一等级结构中的固定产品(支持增加任意产品)
优点:
缺点:
抽象工厂模式:
围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。
优点:
缺点:
参考文献:【精选】设计模式之工厂模式(简单工厂、工厂方法、抽象工厂)_简单工厂模式 抽象工厂模式-CSDN博客1. 工厂方法模式(Factory Method) (yuque.com)2. 抽象工厂模式(Abstract Factory) (yuque.com)