从零开始单排学设计模式「工厂方法模式」青铜 II

阅读本文大概需要 2 分钟。

 

本篇是设计模式系列的第七篇,虽然之前也写过相应的文章,但是因为种种原因后来断掉了,而且发现之前写的内容也很渣,不够系统。

 

所以现在打算重写,加上距离现在也有一段时间了,也算是自己的一个回顾吧!

 

学而时习之,不亦说乎。

 

推荐阅读:

从零开始单排学设计模式「策略模式」黑铁 II

从零开始单排学设计模式「装饰模式」黑铁 I

 

 

目前段位:青铜 II

 

从零开始单排学设计模式「工厂方法模式」青铜 II

 

Let's Go!

 

前言

 

设计模式不是语法,是一种巧妙的写法,能把程序变的更加灵活。架构模式比设计模式大,架构模式是战略,而设计模式是战术。

 

设计模式分为3大类型:创建型,行为型,结构型,总共有23种。

 

工厂方法模式

 

工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

 

该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。

 

工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’(后续会介绍该原则),实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。

 

业务需求

 

在 黑铁 III 中的业务需求,设计了一个计算器,原需求如下:

从零开始单排学设计模式「工厂方法模式」青铜 II

最近leader找到我,告诉我,后续会增加很多种计算功能(求平方,求立方),所以现在要将程序进行改进,以应对之后的功能。

 

之前我们是使用的【简单工厂模式】设计的计算器,而现在为了应对更多的扩展功能,所以现在需要将设计在变的更加容易扩展。

 

代码实现

 

既然,在之后会增加很多的功能,那么首先想到的就是【工厂方法模式】,该模式是【简单工厂模式】的衍生,所以使用它可能很好的满足本次需求。

 

没有观看之前的【简单工厂模式】,可阅读这篇:

从零开始单排学设计模式「简单工厂设计模式」黑铁 III

 

话不多说,马上开干!

 

原先的代码不用修改,只需要进行添加新的工厂接口和工厂即可。

 

原先使用【简单工厂模式】的程序结构图:

从零开始单排学设计模式「工厂方法模式」青铜 II

 

使用【工厂方法模式】之后的程序结构图

从零开始单排学设计模式「工厂方法模式」青铜 II

 

改动的代码

 

先构建一个工厂接口

从零开始单排学设计模式「工厂方法模式」青铜 II

 

然后加减乘除各建一个具体工厂去实现这个接口

从零开始单排学设计模式「工厂方法模式」青铜 II

从零开始单排学设计模式「工厂方法模式」青铜 II

客户端的实现变成了这样

从零开始单排学设计模式「工厂方法模式」青铜 II

这样就大功告成了,项目从 简单工厂模式 变为了 工厂方法模式。

 

简单工厂模式 VS 工厂方法模式

 

简单工厂模式 的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。

 

工厂方法模式 实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。

 

你要想加的功能,本来是改工厂类的,而现在是修改客户端。

 

 

工厂方法模式UML类图

 

从零开始单排学设计模式「工厂方法模式」青铜 II

总结

 

这次的代码是基于上次所写,然后进行改进的,接下来总结一下工厂方法模式。

 

主要解决:主要解决接口选择的问题。

 

何时使用:我们明确地计划不同条件下创建不同实例时。

 

如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。

 

关键代码:创建过程在其子类执行。

 

应用实例: 

        1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。 

        2、Hibernate 换数据库只需换方言和驱动就可以。

 

优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。

 

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

 

使用场景: 

        1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 

        2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 

    3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。

 

注意事项

作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。

 

有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。

 

如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

 

 

 

 

往期精彩回顾

程序员接私活的7大平台利器

每秒 570000 的写入,如何实现?

这40张图送给单身程序员,情人节请一笑而过!

IDEA一定要懂的32条快捷键

世上最污技术解读,我竟然秒懂了。

Bing挂了!百度又“赢了”

遇到卖茶女,应该如何优雅的回复她

我被程序员坑了600万致公司倒闭,当事人逐条反驳:这锅我不背

一千行MySQL详细学习笔记(值得学习与收藏)

七点建议助您写出优雅的Java代码