【设计模式】工厂模式

1.工厂模式介绍

1.1 简单工厂 Simple Factory

把对象的创建封装在一个接口函数里面,通过传入不同的标识,返回创建的对象。

客户不用自己负责new对象,不用了解对象创建的详细过程

1.2 工厂方法 Factory Method

Factory基类,提供了一个纯虚函数(创建产品),定义派生类(具体产品的工厂)负责创建对应的产品,可以做到不同的产品,在不同的工厂里面创建,能够对现有工厂,以及产品的修改关闭。

实际上,很多产品是有关联关系的,属于一个产品簇,不应该放在不同的工厂里面去创建,这样一是不符合实际的产品对象创建逻辑,二是工厂类太多了,不好维护。

1.3 抽象工厂 Abstract Factory :

把有关联关系的,属于一个产品簇的所有产品创建的接口函数,放在一个抽象工厂里面AbstractFactory,派生类(具体产品的工厂)应该负责创建该产品簇里面所有的产品。

假如一类工厂如宝马工厂多做了一项业务如轮胎,那么就得在抽象工厂里面增加一个创建轮胎的产品接口(纯虚函数),所有的工厂都得重写该接口,否则都成了抽象类...

2.简单工厂

提供一个工厂(SimpleFactory)和一个方法(createCar),通过传入不同的参数(标识)来创建不同的派生类对象。

cpp 复制代码
#include<iostream>
#include<memory>
using namespace std;

class Car
{
public:
    Car(string name) : _name(name) { }

    virtual void show() = 0;

protected:
    string _name;
};

class Bmw : public Car
{
public:
    Bmw(string name, int price) : Car(name),_price(price) { }
    void show()
    {
        cout << "获取了一辆宝马汽车"<<endl;
    }
private:
    int _price;
};

class Audi : public Car
{
public:
    Audi(string name, int price) : Car(name), _price(price) { }
    void show()
    {
        cout << "获取了一辆奥迪汽车"<<endl;
    }
private:
    int _price;
};

enum CarType
{
    BMW,AUDI
};

class SimpleFactory
{
public:
    Car *createCar(CarType ct)
    {
        switch (ct)
        {
        case BMW:
            return new Bmw("X6", 100);
        case AUDI:
            return new Audi("A6", 80);
        
        default:
            cerr << "传入工厂的参数不正确:" << ct << endl;
            break;
        }
        return nullptr;
    }
};

int main()
{
    unique_ptr<SimpleFactory> factory(new SimpleFactory());
    unique_ptr<Car> p1(factory->createCar(BMW));
    unique_ptr<Car> p2(factory->createCar(AUDI));
    p1->show();
    p2->show();

    return 0;
}

**缺点:**软件设计要符合"开-闭"原则,而SimpleFactory接口总是变来变去,永远也不封闭。

3.工厂方法

**思路:**给了一个工厂的基类(Factory),通过实现具体产品的工厂(BmwFactory)来生产具体的产品。

cpp 复制代码
#include<iostream>
#include<memory>
using namespace std;

class Car
{
public:
    Car(string name) : _name(name) { }

    virtual void show() = 0;

protected:
    string _name;
};

class Bmw : public Car
{
public:
    Bmw(string name, int price) : Car(name),_price(price) { }
    void show()
    {
        cout << "获取了一辆宝马汽车"<<endl;
    }
private:
    int _price;
};

class Audi : public Car
{
public:
    Audi(string name, int price) : Car(name), _price(price) { }
    void show()
    {
        cout << "获取了一辆奥迪汽车"<<endl;
    }
private:
    int _price;
};

enum CarType
{
    BMW,AUDI
};

// 工厂方法
class Factory
{
public:
    virtual Car* createCar(string name) = 0;    // 工厂方法
};

// 宝马工厂
class BmwFactory : public Factory
{
public:
    Car* createCar(string name)
    {
        return new Bmw(name, 100);
    }
};

// 奥迪工厂
class AudiFactory : public Factory
{
public:
    Car* createCar(string name)
    {
        return new Audi(name, 80);
    }
};

int main()
{
    unique_ptr<Factory> bmwfty(new BmwFactory());
    unique_ptr<Factory> audifty(new AudiFactory());
    unique_ptr<Car> p1(bmwfty->createCar("X6"));
    unique_ptr<Car> p2(audifty->createCar("A8"));
    p1->show();
    p2->show();

    return 0;
}

局限性:

1.宝马和奥迪生产工厂不光造车,还有车灯,车架,发动机等...那么这样的话就要写车灯工厂方法,车架工厂方法、发动机工厂方法等...

2.一个产品对应一个工厂,这会使工厂方法急剧增多

4.抽象工厂

工厂方法 ==> 抽象工厂(对有一组关联关系的产品簇提供产品对象的统一创建)

就是把原来工厂类中有一个纯虚函数,改成多个纯虚函数。然后分别在具体派生工厂中,实现多个产品的实现。

一个工厂实现一个产品簇。

cpp 复制代码
#include<iostream>
#include<memory>
using namespace std;

// 系列产品1
class Car
{
public:
    Car(string name) : _name(name) { }

    virtual void show() = 0;

protected:
    string _name;
};

class Bmw : public Car
{
public:
    Bmw(string name, int price) : Car(name),_price(price) { }
    void show()
    {
        cout << "获取了一辆宝马汽车"<<endl;
    }
private:
    int _price;
};

class Audi : public Car
{
public:
    Audi(string name, int price) : Car(name), _price(price) { }
    void show()
    {
        cout << "获取了一辆奥迪汽车"<<endl;
    }
private:
    int _price;
};

// 系列产品2
class Light
{
public:
    virtual void show() = 0;
};
class BmwLight : public Light
{
public:
    void show() { cout<< "Bmw Light!" << endl; }
};
class AudiLight : public Light
{
public:
    void show() { cout<< "Audi Light!" << endl; }
};


enum CarType
{
    BMW,AUDI
};

// 工厂方法 ==> 抽象工厂(对有一组关联关系的产品簇提供产品对象的统一创建)
class AbstractFactory
{
public:
    virtual Car* createCar(string name) = 0;    // 工厂方法
    virtual Light* createLight() = 0;   // 工厂方法 创建汽车关联的产品,车灯
};

// 宝马工厂
class BmwFactory : public AbstractFactory
{
public:
    Car* createCar(string name)
    {
        return new Bmw(name, 100);
    }
    
    Light* createLight()
    {
        return new BmwLight();
    }
};

// 奥迪工厂
class AudiFactory : public AbstractFactory
{
public:
    Car* createCar(string name)
    {
        return new Audi(name, 80);
    }

    Light* createLight()
    {
        return new AudiLight();
    }
};

int main()
{
    unique_ptr<AbstractFactory> bmwfty(new BmwFactory());
    unique_ptr<AbstractFactory> audifty(new AudiFactory());

    unique_ptr<Car> p1(bmwfty->createCar("X6"));
    unique_ptr<Car> p2(audifty->createCar("A8"));

    unique_ptr<Light> l1(bmwfty->createLight());
    unique_ptr<Light> l2(audifty->createLight());

    p1->show();
    l1->show();

    p2->show();
    l2->show();

    return 0;
}

**局限性:**假如一类工厂如宝马工厂多做了一项业务如轮胎,那么就得在抽象工厂里面增加一个创建轮胎的产品接口(纯虚函数),所有的工厂都得重写该接口,否则都成了抽象类...

相关推荐
Du_XiaoNan8 分钟前
Flowable第三篇、Flowable之任务分配(任务分配、流程变量、候选人和候选人组)
java·开发语言
Clang's Blog10 分钟前
23种设计模式详解(以Java为例)
java·开发语言·设计模式
程序员奇奥15 分钟前
设计模式——简单工厂模型、工厂模式、抽象工厂模式、单例模式、代理模式、模板模式
单例模式·设计模式·抽象工厂模式
main_Java15 分钟前
Android解压zip文件到指定目录
android·java·开发语言
GISer_Jing26 分钟前
Tomcat和Nginx原理说明
服务器·开发语言·javascript
daily_233330 分钟前
数据结构——小小二叉树第二幕(二叉树链式结构的实现以及二叉树的遍历)超详细!!!
数据结构·c++
z54183835 分钟前
装饰器---python
开发语言·python
时光の尘37 分钟前
C语言菜鸟入门·关键字·void的用法
c语言·开发语言·c++·算法·c#·c·关键字
Eric.Lee202140 分钟前
图像上显示中文文本 - python 实现
开发语言·python
小林熬夜学编程42 分钟前
【Linux系统编程】第四十九弹---日志系统构建指南:从基础结构到时间处理与Log类实现
linux·运维·服务器·c语言·开发语言·c++