工厂模式可以分为三种,简单工厂模式,工厂方法模式和抽象工厂模式。
那么,这三种工厂模式长啥样,又为啥会衍生出这三种模式来呢?本篇和大家一起来学习总结一下。
一、简单工厂模式
简单工厂SimpleFactory 负责创建所有实例的内部逻辑。
工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
cpp
//SimpleFactory.h
#pragma once
#include <iostream>
#include <string>
#include <functional>
using namespace std;
#define MYTRACE() { cout << __FUNCTION__ << std::endl; }
/**
* 产品的抽象类(抽象产品类)
*/
class AbstractProduct
{
public:
virtual ~AbstractProduct() {
MYTRACE ()
}
virtual void show() = 0;
};
/**
* 中国产品 (具体产品类)
*/
class ChineseProduct : public AbstractProduct
{
public:
ChineseProduct() {}
~ChineseProduct() {
MYTRACE()
}
void show() override
{
MYTRACE()
}
};
/**
* 日本产品 (具体产品类)
*/
class JapaneseProduct : public AbstractProduct
{
public:
JapaneseProduct() {}
~JapaneseProduct() {
MYTRACE()
}
void show() override
{
MYTRACE()
}
};
/*
* 具体工厂类:负责每一个具体产品的创建业务逻辑
*/
class SimpleFactory
{
public:
enum class ProductType {ChineseProductType,JapaneseProductType};
static AbstractProduct* CreateProduct(ProductType type)
{
switch (type)
{
case SimpleFactory::ProductType::ChineseProductType:
return new ChineseProduct;
case SimpleFactory::ProductType::JapaneseProductType:
return new JapaneseProduct;
}
}
};
cpp
// main.cpp
#include <iostream>
#include "simpleFactory.h"
#include <vector>
int main()
{
std::vector<AbstractProduct*> v;
v.resize(2);
v[0] = SimpleFactory::CreateProduct(SimpleFactory::ProductType::ChineseProductType);
v[1] = SimpleFactory::CreateProduct(SimpleFactory::ProductType::JapaneseProductType);
for (int i = 0; i < v.size(); ++i) {
if (v[i] != nullptr) {
v[i]->show();
delete v[i];
v[i] = nullptr;
}
}
return 0;
}
简单工厂优缺点
优点:
(1)帮助封装:实现组件封装,面向接口编程
(2) 延迟了子类的实例化
(3)解耦合:客户端和具体实现类的解耦合
缺点:
(1)可能增加客户端的复杂度
(2)不方便扩展子工厂
二、工厂方法模式
cpp
//PolymorphicFactory.h
#pragma once
#include <iostream>
#include <string>
#include <functional>
using namespace std;
#define MYTRACE() { cout << __FUNCTION__ << std::endl; }
/**
* 产品的抽象类(抽象产品类)
*/
class AbstractProduct
{
public:
virtual ~AbstractProduct() {MYTRACE()}
virtual void makeProduct() = 0;
};
class AbstractFactory
{
public:
virtual ~AbstractFactory() { MYTRACE() }
virtual AbstractProduct* createProduct() = 0;
};
/**
* 中国产品 (具体产品类)
*/
class ChineseProduct : public AbstractProduct
{
public:
ChineseProduct() {}
~ChineseProduct() { MYTRACE() }
void makeProduct() override { MYTRACE() }
};
class ChineseFactory : public AbstractFactory
{
public:
virtual AbstractProduct* createProduct() override {
MYTRACE()
return new ChineseProduct;
}
};
/**
* 日本产品 (具体产品类)
*/
class JapaneseProduct : public AbstractProduct
{
public:
JapaneseProduct() {}
~JapaneseProduct() { MYTRACE()}
void makeProduct() override{ MYTRACE()}
};
class JapaneseFactory : public AbstractFactory
{
public:
virtual AbstractProduct* createProduct() override {
MYTRACE()
return new JapaneseProduct;
}
};
cpp
#include <iostream>
#include "PolymorphicFactory.h"
#include <cstdio>
int main()
{
// 中国工厂
AbstractFactory* c_factory = new ChineseFactory;
// 开产线
AbstractProduct* c_product = c_factory->createProduct();
// 制造该产品
c_product->makeProduct();
// 日本工厂
AbstractFactory* j_factory = new JapaneseFactory;
// 开产线
AbstractProduct* j_product = j_factory->createProduct();
// 制造该产品
j_product->makeProduct();
return 0;
}
工厂方法优缺点
优点:
(1)帮助封装:实现组件封装,面向接口编程
(2) 延迟了子类的实例化
(3)解耦合:客户端和具体实现类的解耦合
(4)需求改变时改动最小
缺点:
(1)新增功能时,工作量稍大
三、抽象工厂模式
AbstractFactory 模式就是用来解决这类问题:要创建一组相关或者相互依赖的对象 。AbstractFactory模式关键 就是将这一组对象的创建封装到一个用于创建对象的类(ConcreteFactory)中,维护这样一个创建类总比维护n多相关对象的创建过程要简单的多。
cpp
//Product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
#include <iostream>
#include <string>
using namespace std;
#define MYTRACE { cout << __FUNCTION__ << std::endl; }
class AbstractProductA
{
public:
virtual ~AbstractProductA(){MYTRACE}
protected:
AbstractProductA(){MYTRACE}
private:
};
class AbstractProductB
{
public:
virtual ~AbstractProductB(){MYTRACE}
protected:
AbstractProductB(){MYTRACE}
private:
};
class ProductA1: public AbstractProductA
{
public:
ProductA1(){MYTRACE}
~ProductA1(){MYTRACE}
protected:
private:
};
class ProductA2:public AbstractProductA
{
public:
ProductA2(){MYTRACE}
~ProductA2(){MYTRACE}
protected:
private:
};
class ProductB1: public AbstractProductB
{
public:
ProductB1(){MYTRACE}
~ProductB1(){MYTRACE}
protected:
private:
};
class ProductB2: public AbstractProductB
{
public:
ProductB2(){MYTRACE}
~ProductB2(){MYTRACE}
protected:
private:
};
#endif //_PRODUCT_H_
cpp
// factory.h
#ifndef FACTORY_H
#define FACTORY_H
#include "product.h"
class AbstractFactory
{
public:
virtual ~AbstractFactory(){}
virtual AbstractProductA* createProductA() = 0;
virtual AbstractProductB* createProductB() = 0;
protected:
AbstractFactory(){}
};
/*!
* \brief The ConcreteFactory1 class 生产一类产品:A1和B1
*/
class ConcreteFactory1: public AbstractFactory
{
public:
ConcreteFactory1(){}
~ConcreteFactory1(){}
AbstractProductA* createProductA() override{ return new ProductA1;}
AbstractProductB* createProductB() override{ return new ProductB1;}
protected:
private:
};
/*!
* \brief The ConcreteFactory2 class 生产二类产品:A2和B2
*/
class ConcreteFactory2:public AbstractFactory
{
public:
ConcreteFactory2(){}
~ConcreteFactory2(){}
AbstractProductA* createProductA() override{ return new ProductA2;}
AbstractProductB* createProductB() override{ return new ProductB2;}
protected:
private:
};
#endif // FACTORY_H
cpp
#include <iostream>
#include "factory.h"
int main(/*int argc, char *argv[]*/)
{
AbstractFactory* cf1 = new ConcreteFactory1;
cf1->createProductA();
cf1->createProductB();
AbstractFactory* cf2 = new ConcreteFactory2;
cf2->createProductA();
cf2->createProductB();
return 0;
}
抽象工厂模式优缺点
优点:
- 抽象工厂封装了变化,封装了对象创建的具体细节
- 增加新的产品族很方便,无须修改已有系统
- 针对接口进行编程而不是针对具体产品对象进行编程
缺点:
- 增加新的产品等级结构需对原系统做较大修改(违背开放封闭)
四、总结
在前面三个部分,我们说了三种不同工厂模式的实现,以及各自的优缺点。那么,是不是说抽象工厂模式就是最好的呢,显然不是,具体的使用哪种模式,还要结合业务场景需求~