设计模式学习(五) 工厂方法模式和抽象工厂模式

工厂方法模式和抽象工厂模式


这是个人学习编程模式的系列学习笔记第五篇。
采用Qt Creator进行编写,但尽量采用C++基础语法。
之前学习了简单工厂模式。在简单工厂模式的基础上,为解决简单工厂的缺陷(添加新产品不光需要添加新的产品类,还需要修改简单工厂类,不能很好满足面向对象编程对修改封闭,对扩展开放的要求),进一步发展为工厂方法模式和抽象工厂模式。
工厂方法模式和抽象工厂模式都属于对象创建模式。
工厂方法模式(FACTORY METHOD):定义一个用于创建对象的接口,让子类决定实例化哪一个类。 Factory Method使一个类的实例化延迟到其子类。
抽象工厂模式(ABSTRACT FACTORY):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
个人理解:
简单工厂模式就像一个可以生产多种产品的工厂,根据订单要求进行生产。如果有新类型的产品订单,需要调整生产线。
工厂方法模式就像是有一个公司下有多个工厂,每个工厂只负责生产专门的产品。如果有新类型的产品,再建一个新的工厂进行生产。这样的好处是原有工厂生产线不需要动,坏处是如果产品只是型号不同,也需要建新工厂,投入比较大。
抽象工厂模式就像是一个公司有多个工厂,并且每个工厂生产系列产品,有多条生产线,每个生产线生产系列产品中的单一型号产品。只要是产品没大的变化,就都在一个工厂内通过添加新生产线来完成。

场景描述

之前实验简单工厂模式的时候,假设了一个生产不同糕点的烘焙工厂。现在假设这家工厂赚钱了,业务扩大了,需要扩展生产工厂,这时候面临两种方式,一种是继续模仿之前的方式,每个工厂都可以生产各种糕点,但这一容易调度混乱,尤其是要增加新生产品种,就需要改原有工厂的生产线,需要停工。另外一种方式是每个工厂只生产指定的糕点,一个工厂只生产自己指定的产品,这样的好处是如果有新产品需求,再建一个新工厂就可以了,之前的生产继续生产,不受影响。这就是工厂方法模式。
随着这家公司烘焙生意越来越好,为满足特殊用户需求,增加有糖和无糖的分类。同时如果每个型号的产品都建一个工厂,工厂数量就太多了。因此将简单工厂模式和工厂方法模式结合一下,按有糖和无糖分为两个工厂,从而在避免工厂数量暴增的问题。同时为了解决简单工厂存在的问题(比如新增产品需要修改生产类的问题),引入反射等技术,通过根据传入的参数生成对应的类(工厂类中不是采用switch模式,这部分现在没有涉及,先不实验了)。

设计思路

工厂方法模式:
定义一个点心类作为基类。
定义一个工厂类作为生成点心工厂的基类。
通过点心类派生各种具体的点心,比如蛋糕、面包。
通过工厂类派生具体点心生成厂家,比如蛋糕工厂、面包工厂。
抽象工厂模式:
为有糖点心和无糖点心各定义一个基类。然后有糖点心类派生出普通蛋糕、普通面包;无糖点心类(或许叫代糖类点心更合适,没有糖的点心有啥吃的?)派生出无糖蛋糕、无糖面包。
定义一个工厂类作为生成点心工厂的基类。
通过工厂类派生系列点心生成厂家,比如蛋糕工厂、面包工厂。负责各种点心生产。

UML

工厂方法模式:
在这里插入图片描述
抽象工厂模式:
在这里插入图片描述

代码

工厂方法模式

#include <iostream>

using namespace std;

class Dessert
{
public:
    virtual void show() = 0;
};

class Cake : public Dessert
{
public:
    void show() {cout<<"Make a cake!\n";}
};

class Bread : public Dessert
{
public:
    void show() {cout<<"Make a bread!\n";}
};

class Factory
{
public:
    virtual Dessert* creat() = 0;
};

class CakeFactory : public Factory
{
public:
    Dessert* creat() {return new Cake();}
};

class BreadFactory : public Factory
{
public:
    Dessert* creat() {return new Bread();}
};

int main()
{
    Factory* factory = new BreadFactory();
    Dessert* dessert = factory->creat();
    dessert->show();
    delete dessert;
    delete factory;

    return 0;
}

抽象工厂模式

#include <iostream>

using namespace std;

class NormalDessert
{
public:
    virtual void show() = 0;
};

class NormalCake : public NormalDessert
{
public:
    void show() {cout<<"Make a normal cake!\n";}
};

class NormalBread : public NormalDessert
{
public:
    void show() {cout<<"Make a normal bread!\n";}
};


class NoSugarDessert
{
public:
    virtual void show() = 0;
};

class NoSugarCake : public NoSugarDessert
{
public:
    void show() {cout<<"Make a nosugar cake!\n";}
};

class NoSugarBread : public NoSugarDessert
{
public:
    void show() {cout<<"Make a nosugar bread!\n";}
};

class Factory
{
public:
    virtual NormalDessert* creatNormal() = 0;
    virtual NoSugarDessert* creatNoSugar() = 0;
};

class CakeFactory : public Factory
{
public:
    NormalDessert* creatNormal() {return new NormalCake;}
    NoSugarDessert* creatNoSugar() {return new NoSugarCake;}
};

class BreadFactory : public Factory
{
public:
    NormalDessert* creatNormal() {return new NormalBread;}
    NoSugarDessert* creatNoSugar() {return new NoSugarBread;}
};

int main()
{
    Factory* factory = new BreadFactory();
    NormalDessert* normal = factory->creatNormal();
    NoSugarDessert* nosugar = factory->creatNoSugar();
    normal->show();
    nosugar->show();
    delete nosugar;
    delete normal;
    delete factory;

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值