博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
嘻哈说:设计模式之工厂方法模式
阅读量:7027 次
发布时间:2019-06-28

本文共 4432 字,大约阅读时间需要 14 分钟。

1、嘻哈说

这首歌还没写不能发

因为本节的工厂方法模式与抽象工厂模式存在关联度,所以会在下一节《抽象工厂模式》中混成一首歌发。

2、简单工厂模式的定义

现实中的工厂,是用来生产产品的,而代码中的工厂,则是创建对象的,

用来创建对象,那肯定就是创建型模式了。

我们经常会用到三种和工厂相关的设计模式:简单工厂模式、工厂方法模式、抽象工厂模式。

这节咱们要说的是——工厂方法模式。

不过,再说工厂方法之前,我们要先说下简单工厂模式。我们从简单的开始入手,由简入繁。

简单工厂模式呢,它不属于Gof23种设计模式之一,但它在实际的项目中经常被用到,所以我们还是很有必要学习,并且它的思想也非常简单,可以说是工厂方法模式的一个引导。

我们来看一下简单工厂方法的定义。

又称为静态工厂模式,由一个工厂对象决定创建出哪一种产品类的实例。

注意这里的定义,是一个工厂对象

怎么实现呢?实现的套路是什么?

定义一个工厂类,可以根据参数的不同返回不同类的实例,被创建的实例通常有共同的父类。

3、场景

场景与建造者模式有点类似,还是熟悉的饺子,还是熟悉的配方,还是熟悉的味道,扯远了...

美食饺子

番茄餐厅的后厨。

厨师长:老板,我听说隔壁餐厅买来了一个机器,包饺子神器,一输入参数,饺子直接出锅,高科技呀,跟饺子工厂似的。

老板:你的意思是咱们也去买个?

厨师长:嗯,我是想提这个建议的,一键出饺子,想想心里还有点小激动呢。

老板:你不会是为了图省事吧?

求生欲极强的厨师长:当然不是,我是觉得饺子神器效率高,能够给我们饭店带来更大的价值。

老板:嗯,那我同意了,钱从你工资里扣。

委屈的厨师长:老板,这样不合适吧?我上有老,下有...

老板:打住,逗你的,看把你给吓得。效率提高但味道降低,这种神器咱们饭店不会用的。

我们今天的例子,就是饺子工厂,可以生产各种饺子馅、皮。

4、简单工厂模式

简单工厂模式的UML类图。

package com.fanqiekt.factory.simple;/** * 饺子馅 * * @Author: 番茄课堂-懒人 */public interface IStuffing {    void make();}复制代码

IStuffing:产品(饺子馅)的接口,共有的父类。

make()就是制造饺子皮的方法。

package com.fanqiekt.factory.simple;/** * 猪肉大葱馅 * @Author: 番茄课堂-懒人 */public class PorkStuffing implements IStuffing {    @Override    public void make() {        System.out.println("制作猪肉大葱馅");    }}复制代码
package com.fanqiekt.factory.simple;/** * 茴香鸡蛋馅 * @Author: 番茄课堂-懒人 */public class FoeniculumVulgareStuffing implements IStuffing {    @Override    public void make() {        System.out.println("制作茴香鸡蛋馅");    }}复制代码
package com.fanqiekt.factory.simple;/** * 韭菜鸡蛋馅 * @Author: 番茄课堂-懒人 */public class ChineseChivesStuffing implements IStuffing {    @Override    public void make() {        System.out.println("制作韭菜鸡蛋馅");    }}复制代码

具体的产品类,饺子馅中的大户:猪肉大葱馅、茴香鸡蛋馅、韭菜鸡蛋馅。

package com.fanqiekt.factory.simple;/** * 饺子馅工厂类 * @Author: 番茄课堂-懒人 */public class StuffingFactory {    public static IStuffing getStuffing(String key){        IStuffing stuffing = null;        switch (key){            case "猪肉大葱":                stuffing = new PorkStuffing();                break;            case "韭菜鸡蛋":                stuffing = new ChineseChivesStuffing();                break;            case "茴香鸡蛋":                stuffing = new FoeniculumVulgareStuffing();                break;        }        return stuffing;    }}复制代码

StuffingFactory:饺子馅工厂类。

简单工厂中只有一个工厂类,并且提供了一个静态公有方法,可以根据参数的不同返回不同类的实例。

这也是简单方法为什么要被称之为静态工厂模式的原因。

package com.fanqiekt.factory.simple;/** * 客户端 * @Author: 番茄课堂-懒人 */public class Client {    public static void main(String args[]){        IStuffing stuffing = StuffingFactory.getStuffing("猪肉大葱");        stuffing.make();        System.out.println("------------");        stuffing = StuffingFactory.getStuffing("韭菜鸡蛋");        stuffing.make();        System.out.println("------------");        stuffing = StuffingFactory.getStuffing("茴香鸡蛋");        stuffing.make();    }}复制代码

客户端类。

我们可以看出,简单工厂不愧为简单工厂,就是赤裸裸的简单。

但简单并不普通,它完美的展现了工厂方法的思想,让工厂创建对象,而不是对象A去创建对象B。

这样可以避免对象A与对象B之间的耦合。

我们运行一下,看结果。

制作猪肉大葱馅------------制作韭菜鸡蛋馅------------制作茴香鸡蛋馅复制代码

5、工厂方法模式的定义

如果按照简单工厂的写法,在不使用java的反射的前提下,扩展性是很差的。

如果添加一种饺子馅,必须修改工厂中的判断。

所以我们来介绍一下另外一种工厂模式——工厂方法模式,下面,我们有请男主出场。

我们先来看看,工厂方法模式的官方定义:

定义一个用于创建对象的接口,让子类决定实例化哪一个类。

从定义中,我们可以看出实现的套路:定一个创建对象的接口,然后每个工厂去实现该接口实例化特定的对象,这样就使一个类的实例化延迟到其子类。

每一个产品都有相应的工厂,这就是与简单工厂模式最大的区别。

然后,调用者可以自由的 选择使用哪个工厂去创建对象。

6、工厂方法模式

工厂方法模式的UML类图。

产品(饺子馅)与简单工厂模式的代码一致,这里就不贴出来了。

package com.fanqiekt.factory.method;/** * 工厂接口 * @Author: 番茄课堂-懒人 */public interface IFactory {    IStuffing getStuffing();}复制代码

IFactory:工厂的接口。

定义一个用于创建对象的接口。

getStuffing()获得产品(饺子馅)的方法,交给具体的子类来实现。使一个类的实例化延迟到其子类。

package com.fanqiekt.factory.method;/** * 猪肉大葱馅工厂 * @Author: 番茄课堂-懒人 */public class PorkFactory implements IFactory {    @Override    public IStuffing getStuffing() {        return new PorkStuffing();    }}复制代码
package com.fanqiekt.factory.method;/** * 茴香鸡蛋馅工厂 * @Author: 番茄课堂-懒人 */public class FoeniculumVulgareFactory implements IFactory {    @Override    public IStuffing getStuffing() {        return new FoeniculumVulgareStuffing();    }}复制代码
package com.fanqiekt.factory.method;/** * 韭菜鸡蛋馅工厂 * @Author: 番茄课堂-懒人 */public class ChineseChivesFactory implements IFactory {    @Override    public IStuffing getStuffing() {        return new ChineseChivesStuffing();    }}复制代码

具体的工厂类。

为每个产品(饺子馅)提供一个工厂类:猪肉大葱馅工厂、茴香鸡蛋馅工厂、韭菜鸡蛋馅工厂。

这样的设计,扩展起来也非常的方便,例如增加三鲜馅,只需要增加产品类(三鲜馅)、工厂类(三鲜馅)就可以了。不会影响其他。

7、区别

简单工厂模式,只有一个工厂类,根据参数的不同返回不同类的实例。

工厂方法模式,定义一个创建对象的接口,存在实现该接口的多个工厂类。调用者选择使用哪个工厂。

8、END

从下一节课程开始,《嘻哈说——设计模式》系列的课程将不在其他渠道发布,改为公众号《番茄课堂》独家发布,期待大家的关注。

今天就先说到这里,下一节说《抽象工厂模式》,感谢大家支持。

转载地址:http://hjmxl.baihongyu.com/

你可能感兴趣的文章
JS常用方法(获取Class、获取元素样式、事件监听、cookie、ajax等)
查看>>
BZOJ 1084 最大子矩阵
查看>>
2018杭电多校第三场1007(凸包,极角排序)
查看>>
django中orm的简单操作
查看>>
Mybatis知识(1)
查看>>
[CentOS] 7 不执行文件 /etc/rc.d/rc.local
查看>>
模态窗口的各个属性
查看>>
10.28 (上午) 开课一个月零二十四天 (数据访问)
查看>>
为什么你应该(从现在开始就)写博客
查看>>
小技巧积累
查看>>
Java JDBC链接Oracle数据库
查看>>
Moss2010 部署命令
查看>>
Git 操作分支
查看>>
Grid search in the tidyverse
查看>>
hdu 三部曲 Contestants Division
查看>>
day22——创建表、增加数据、查询数据
查看>>
c# 调用 c dll 例子
查看>>
【C#】string格式的日期转为DateTime类型及时间格式化处理方法
查看>>
实验十三:窗口设计
查看>>
python解析XML的三种方法
查看>>