从零开始单排学设计模式「工厂方法模式」青铜 II
阅读本文大概需要 2 分钟。
本篇是设计模式系列的第七篇,虽然之前也写过相应的文章,但是因为种种原因后来断掉了,而且发现之前写的内容也很渣,不够系统。
所以现在打算重写,加上距离现在也有一段时间了,也算是自己的一个回顾吧!
学而时习之,不亦说乎。
推荐阅读:
目前段位:青铜 II
Let's Go!
前言
设计模式不是语法,是一种巧妙的写法,能把程序变的更加灵活。架构模式比设计模式大,架构模式是战略,而设计模式是战术。
设计模式分为3大类型:创建型,行为型,结构型,总共有23种。
工厂方法模式
工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。
工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’(后续会介绍该原则),实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。
业务需求
在 黑铁 III 中的业务需求,设计了一个计算器,原需求如下:
最近leader找到我,告诉我,后续会增加很多种计算功能(求平方,求立方),所以现在要将程序进行改进,以应对之后的功能。
之前我们是使用的【简单工厂模式】设计的计算器,而现在为了应对更多的扩展功能,所以现在需要将设计在变的更加容易扩展。
代码实现
既然,在之后会增加很多的功能,那么首先想到的就是【工厂方法模式】,该模式是【简单工厂模式】的衍生,所以使用它可能很好的满足本次需求。
没有观看之前的【简单工厂模式】,可阅读这篇:
话不多说,马上开干!
原先的代码不用修改,只需要进行添加新的工厂接口和工厂即可。
原先使用【简单工厂模式】的程序结构图:
使用【工厂方法模式】之后的程序结构图
改动的代码
先构建一个工厂接口
然后加减乘除各建一个具体工厂去实现这个接口
客户端的实现变成了这样
这样就大功告成了,项目从 简单工厂模式 变为了 工厂方法模式。
简单工厂模式 VS 工厂方法模式
简单工厂模式 的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
工厂方法模式 实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。
你要想加的功能,本来是改工厂类的,而现在是修改客户端。
工厂方法模式UML类图
总结
这次的代码是基于上次所写,然后进行改进的,接下来总结一下工厂方法模式。
主要解决:主要解决接口选择的问题。
何时使用:我们明确地计划不同条件下创建不同实例时。
如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。
关键代码:创建过程在其子类执行。
应用实例:
1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
2、Hibernate 换数据库只需换方言和驱动就可以。
优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
使用场景:
1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
注意事项:
作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。
有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。
如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
往期精彩回顾