C++设计模式——工厂模式 :简单工厂、工厂方法、抽象工厂

工厂模式可以分为三种,简单工厂模式,工厂方法模式和抽象工厂模式。

那么,这三种工厂模式长啥样,又为啥会衍生出这三种模式来呢?本篇和大家一起来学习总结一下。

一、简单工厂模式

简单工厂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;
}


抽象工厂模式优缺点
优点:

  1. 抽象工厂封装了变化,封装了对象创建的具体细节
  2. 增加新的产品族很方便,无须修改已有系统
  3. 针对接口进行编程而不是针对具体产品对象进行编程

缺点:

  1. 增加新的产品等级结构需对原系统做较大修改(违背开放封闭)

四、总结

在前面三个部分,我们说了三种不同工厂模式的实现,以及各自的优缺点。那么,是不是说抽象工厂模式就是最好的呢,显然不是,具体的使用哪种模式,还要结合业务场景需求~

相关推荐
一点媛艺2 小时前
Kotlin函数由易到难
开发语言·python·kotlin
姑苏风2 小时前
《Kotlin实战》-附录
android·开发语言·kotlin
奋斗的小花生3 小时前
c++ 多态性
开发语言·c++
魔道不误砍柴功3 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
闲晨3 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
老猿讲编程4 小时前
一个例子来说明Ada语言的实时性支持
开发语言·ada
UestcXiye5 小时前
《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列
c++·计算机网络·ip·tcp
Chrikk5 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*5 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue5 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang