设计模式 (5)——工厂方法模式(Factory Method,创建型)

1.概述

使用设计模式可以提高代码的可复用性、可扩充性和可维护性。工厂方法模式(Factory Method Pattern)属于创建型模式,定义一个创建对象的接口函数,但由子类决定实例化某一个类,让工厂类把实例化推迟到子类。

在前面的设计模式(四)——简单工厂模式中我们介绍了简单工厂模式,接下来将介绍下工厂方法模式,它同样是创建型设计模式,有相似之处,但又有些不同,文章的末尾会介绍他们之间的不同。

这里借用一下网上的资源,类图结构如下:

基类:抽象产品类。 子类:具体产品类。 工厂类:即抽象工厂类,提供了一个创建对象的方法,也称为“工厂方法”,该方法返回一个具体产品类的对象。 子类工厂:具体工厂类,实现抽象工厂类的“工厂方法”,来创建某个具体产品类实例。每一个子类工厂,负责创建一个具体产品类的对象。

2.工厂方法模式具体应用

请参考设计模式(四)——简单工厂模式这篇文章。 还是以生产比萨为例,比萨店需要根据客户订单,生产不同口味的比萨。这里比萨生产不是交由一个厨房生产,而是不同口味比萨交由不同厨房来专门制作。

还是以C++为例,首先实现我们的抽象比萨类和具体口味的比萨。

class Pizza {
public:
    virtual string getDescription() = 0;
};


//蛤蜊比萨
class ClamPizza :public Pizza {
    string name="蛤蜊比萨";
public:
    string getDescription() {
        return name + " 价格45元";
    }
};

//素食比萨
class VeggiePizza :public Pizza {
    string name = "素食比萨";
public:
    string getDescription() {
        return name+ " 价格26元";;
    }
};

//芝士比萨
class CheesePizza :public Pizza {
    string name = "比萨";
public:
    string getDescription() {
        return name + " 价格38元";;
    }
};

下面实现抽象工厂和制作不同口味比萨的厨房。

//抽象工厂,提供创建创建对象的接口createPizza()
class PizzaFactory {
public:
    virtual Pizza* createPizza() = 0;
};

//具体工厂类,创建蛤蜊比萨
class ClamPizzaFactory :PizzaFactory {
public:
    virtual Pizza* createPizza() {
        return new ClamPizza;
    }
};

//具体工厂类,创建素食比萨
class VeggiePizzaFactory :public PizzaFactory{
public:
    virtual Pizza* createPizza() {
        return new VeggiePizza;
    }       
};

//具体工厂类,创建芝士比萨
class CheesePizzaFactory :public PizzaFactory {
public:
    virtual Pizza* createPizza() {
        return new CheesePizza;
    }
};

下面开始生产我们需要的比萨。

int main() {

    Pizza* clamPizza = (new ClamPizzaFactory)->createPizza();   //实例化蛤蜊比萨
    cout<<clamPizza->getDescription()<<endl;
    Pizza* veggiePizza = (new VeggiePizzaFactory)->createPizza();   //实例化素食比萨
    cout << veggiePizza->getDescription() << endl;
    Pizza* cheesePizza = (new CheesePizzaFactory)->createPizza();   //实例化芝士比萨
    cout << cheesePizza->getDescription() << endl;
    system("pause");
}

程序输出结果:

蛤蜊比萨 价格45元
素食比萨 价格26元
比萨 价格38元

工厂方法模式实现也比较简单,上面的类结构图如下所示:

3.简单工厂和工厂方法模式的比较

简单工厂模式: 专门定义一个工厂类负责创建其他类的实例,最大的优点在于工厂类中包含了必要的逻辑,根据客户需要的条件动态实例化相关的类。其缺点就是生产新产品时需要更改简单工厂类的代码,这违背了开放封闭原则。

工厂方法模式: 提供创建对象的接口,让子类去决定具体实例化的对象,把简单的内部逻辑判断移到了客户端代码。工厂方法克服了简单工厂违背开放封闭原则的缺点,又保持了封装对象创建过程的优点。

下一篇将讲解抽象工厂模式,并与二者进行对比。

4.小结

(1)工厂方法模式属于创建型模式,定义一个创建对象的接口函数,但由子类决定实例化某一个类,让工厂类把实例化推迟到子类。 (2)工厂方法模式坚持了依赖倒置原则,高层模块不依赖于底层模块,二者都依赖于抽象。高层模块是比萨店前台,底层模块是具体口味的披萨,二者都依赖抽象类Pizza。


参考文献

[1]简单工厂模式和工厂方法模式

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏AI科技大本营的专栏

10分钟快速入门Python函数式编程

本文,你会了解到什么是函数式编程,以及如何用 Python 进行函数式编程。你还会了解到列表解析和其他形式的解析。

13920
来自专栏前端正义联盟

我来重新学习 javascript 的面向对象(part 3)

续上一集内容,有一些数据不需要共享的时候,但是又想实现共享数据处理,鱼与熊掌,都要兼得(老板就是这么霸气),那么经过工程师们的智慧交流,他们发现现实并非那么残酷...

7210
来自专栏编程

浅谈如何定义和调用Python的函数

函数是python编程核心内容之一,笔者在本文中主要介绍下函数的概念和基础函数相关知识点。函数是什么?有什么作用、定义函数的方法及如何调用函数。 函数是可以实现...

19150
来自专栏小詹同学

Leetcode打卡 | No.23 合并 k 个有序链表

欢迎和小詹一起定期刷leetcode,每周一和周五更新一题,每一题都吃透,欢迎一题多解,寻找最优解!这个记录帖哪怕只有一个读者,小詹也会坚持刷下去的!

15410
来自专栏贺贺的前端工程师之路

《JavaScript语言精粹》学习笔记

在JavaScript中,/ *可能出现在正则表达式字面量里,所以块注释对于被注释的代码块来说是<u>不安全的</u>。

8120
来自专栏zhisheng

运算优先级、结合性、求值顺序、副作用和顺序点

标题中这几个概念,是很多C/C++程序员在表达式上容易出问题或不清楚的地方,虽然这些概念在很多语言都有体现,但C里面特别明显,所以就以C语言为例子总结下 运算...

50770
来自专栏小樱的经验随笔

python易错盲点排查之+=与+的区别分析以及一些赋值运算踩过的坑

问题1. int和list是不一样的 >>> a=1 >>> b=a >>> a+=1 >>> a,b (2, 1) >>> a=[1,2,3,4] >>> b...

29590
来自专栏desperate633

设计模式之工厂方法模式(FACTORY METHOD)问题模拟工厂方法模式分析依赖倒置原则小结

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。 我们依然接着简单工厂模式提出的披萨店问题继续探讨

10440
来自专栏诸葛青云的专栏

想当黑客?浅谈C语言编程:不会这个知识就别想了!

看到标题点进来的朋友,应该对黑客这个名词很敏感吧?我想应该是这样的,但是你们知道作为一名黑客需要学习哪些知识吗?小编不是什么大佬,但小编可以明确的告诉你,学习C...

29100
来自专栏从流域到海域

《笨办法学Python》 第29课手记

《笨办法学Python》 第29课手记 本节课讲if语句。 本节内容比较简单,如果觉得你的代码没有错误,但运行时报错,那么你的代码肯定有错误。相信我解释器是已经...

20960

扫码关注云+社区

领取腾讯云代金券