C++设计模式--工厂模式

工厂模式大量应用于软件开发中,是一种非常重要的设计模式。

为什么需要工厂模式?

设计模式有一原则:面向抽象编程,不应该针对实现编程。在面向对象编程中我们经常需要”实例化“很多对象,每当实例化一个对象的时候,其实你的代码已经与”具体“的对象绑定在一起了。这就违背了我们的设计原则,所以需要一种设计模式来实现不依赖具体对象编程。

例如以下代码:

int main()
{
    CarA carA = new CarA();
    CarB carB = new CarB();
    ...
    return 0;
}

CarA,CarB都是一个实例对象,这样的代码不易扩展,一旦创建了大量的实例,程序后期的维护必定耗费大量精力。。。

 

工厂模式的出现就是为了增强程序的可维护性与可扩展性。

工厂模式主要有以下三种:

  1. 简单工厂模式
  2. 工厂方法模式
  3. 抽象工厂模式

1.简单工厂模式。

简单工厂模式是根据传入的参数动态地创建相应的对象实例。

以下是C++的一个简单工厂模式的例子。

汽车抽象类:

#ifndef __CAR_H__
#define __CAR_H__

#include <string>
class Car
{
public:
    std::string getName() const
    {
        return m_name;
    }
    virtual double getPrice() = 0;
public:
    std::string m_name = "Unknow";
};
#endif

具体汽车类(一共两种商品,分别是CarA和CarB):

//carproduct.h
#ifndef __CARPRODUCT_H__
#define __CARPRODUCT_H__

#include "car.h"
class CarA : public Car
{
public:
    CarA();
    ~CarA();
    virtual double getPrice() override;
};

class CarB : public Car
{
public:
    CarB();
    ~CarB();
    virtual double getPrice() override;
};
#endif
//carproduct.cc
#include "carproduct.h"

#include <string>

CarA::CarA()
{
    m_name = "CarA";
}

CarA::~CarA()
{
}

double CarA::getPrice()
{
    return 123456.0;
}

CarB::CarB()
{
    m_name = "CarB";
}

CarB::~CarB()
{
}

double CarB::getPrice()
{
    return 654321.0;
}

简单汽车工厂:

//carfactory.h
#ifndef __CARFACTORY_H__
#define __CARFACTORY_H__

#include "carproduct.h"

enum class CAR_TYPE{CARA,CARB};

class CarFactory
{
public:
    Car* createCar(CAR_TYPE TYPE);
};
#endif
#include "carproduct.h"

#include <string>

CarA::CarA()
{
    m_name = "CarA";
}

CarA::~CarA()
{
}

double CarA::getPrice()
{
    return 123456.0;
}

CarB::CarB()
{
    m_name = "CarB";
}

CarB::~CarB()
{
}

double CarB::getPrice()
{
    return 654321.0;
}

使用简单汽车工厂生产汽车:

#include <iostream>
#include "car.h"
#include "carfactory.h"

using namespace std;

int main()
{
    CarFactory carFactory;
    Car* car = carFactory.createCar(CAR_TYPE::CARA);
    cout << car->getName() <<"    "<<car->getPrice() << endl;
    delete car;
    return 0;
}

Linux下编译运行:

g++ -std=c++11 -o main main.cc carproduct.cc carfactory.cc
./main

上述的汽车生产过程并没有引入具体的汽车商品(即carproduct.h),也就是说客户并不需要知道汽车生产的过程,只需要知道有哪些类型的车即可,也就是与特定的商品无关,符合松解耦的设计原则。

 

简单工厂模式优缺点

优点:

  1. 隐藏了对象创建的细节
  2. 程序扩展性好,需要增添新的产品的时候改动工厂类即可,客户代码基本不用修改。
  3. 遵循了依赖倒转原则。

缺点:

  1. 要求子类不能太多,太多的话工厂类将相当的庞大并且不易管理
  2. 每添加一个产品子类,都必须修改工厂类,这违背了开放-封闭原则。

 

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

2.工厂方法模式

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类实例化推迟到子类。

                                                                                                                                                                 --《Head First设计模式》

为什么会有工厂方法模式和抽象工厂模式?

上面的讨论我们知道简单工厂模式违背了设计原则的”开放-封闭原则“,也就是说新增一个商品需要对旧的类进行修改。现在我们将工厂实例化推迟到子类,那么每新增一个商品,只需要新增一个生产该商品的类即可,这样就避免了修改原有的类,维护了”对扩展开放,对修改关闭“原则。

 

工厂方法模式基本与简单工厂模式相似,只需要修改工厂类:

//carfactory.h
#ifndef __CARFACTORY_H__
#define __CARFACTORY_H__

#include "carproduct.h"

class CarFactory
{
public:
    virtual Car* createCar() = 0;
};

class CarAFactory : public CarFactory
{
public:
    virtual Car* createCar() override;
};

class CarBFactory : public CarFactory
{
public:
    virtual Car* createCar() override;
};
#endif
//carfactory.cc
#include "carfactory.h"

Car* CarAFactory::createCar()
{
    Car* car = new CarA();
    return car;
}

Car* CarBFactory::createCar()
{
    Car* car = new CarB();
    return car;
}

 

工厂方法优缺点:

优点:

与简单工厂模式基本一样,但是维护了”开放--关闭“的设计原则。

缺点:

需要为每个商品创建一个工厂子类,可能会造成工厂类过多和臃肿。

 

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

3.抽象工厂模式

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体的类。

                                                                                                                                                                  --《Head First设计模式》

抽象工厂模式与工厂方法模式看起来很相似,其实他们有区别的:

  1. 工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
  2. 工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

(来源于网络)

 

假设A,B两个品牌即生产汽车(Car)同时也生产自行车(Bicycle),那么这时候可以用抽象工厂模式:

#ifndef __FACTORY_H__
#define __FACTORY_H__

#include "carproduct.h"
#include "bicycleproduct.h"

class Factory
{
public:
    virtual Car* createCar() = 0;
    virtual Bicycle* createBicycle() = 0;
};

class AFactory : public Factory
{
public:
    virtual Car* createCar() override;
    virtual Bicycle* createBicycle() override;
};

class BFactory : public Factory
{
public:
    virtual Car* createCar() override;
    virtual Bicycle* createBicycle() override;
};
#endif
#include "factory.h"

Car* AFactory::createCar()
{
    Car* car = new CarA();
    return car;
}

Bicycle* AFactory::createBicycle()
{
    Bicycle* bicycle = new BicycleA();
    return bicycle;
}

Car* BFactory::createCar()
{
    Car* car = new CarB();
    return car;
}

Bicycle* BFactory::createBicycle()
{
    Bicycle* bicycle = new BicycleB();
    return bicycle;
}

 

Linux下运行:

g++ -std=c++11 -o main main.cc carproduct.cc bicycleproduct.cc factory.cc
./main

 

抽象工厂模式优缺点:

优点:

  1. 封装了产品的创建,使得不需要知道具体是哪种产品,只需要知道是哪个工厂就行了。
  2. 可以支持不同类型的产品,使得模式灵活性更强。
  3. 可以非常方便的使用一族中间的不同类型的产品。

缺点:

  1. 结构太过臃肿,如果产品类型比较多,或者产品族类比较多,就会非常难于管理。
  2. 每次如果添加一组产品,那么所有的工厂类都必须添加一个方法,这样违背了开放-封闭原则。所以一般适用于产品组合产品族变化不大的情况。

(来源于网络)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值