1.设计模式——工厂模式

在说设计模式之前我们要搞清楚如下三个问题

问题一:什么是设计模式?

设计模式是在软件开发中,经过验证的,用于解决在特定环境下、重复出现的、特定问题的解决方案。

问题二:设计模式有哪些?

在GoF著作中所讲述的设计模式有23种,分别为外观模式、适配器模式、单例模式、工厂方法模式、抽象工厂模式、生成器模式、原型模式、中介者模式、代理模式、观察者模式、命令模式、迭代器模式、组合模式、模板方法模式、策略模式、状态模式、备忘录模式、享元模式、解释器模式、装饰模式、职责链模式、桥接模式、访问者模式。

问题三:什么是面向接口编程?

在回答该问题之前,我们先回顾一下接口额内容。

1.接口的概念?

在Java中接口是一种特殊的抽象类

2.接口用来干什么?

通常用接口来定义实现类的外观,就相当于一份契约,根据外部应用需要的功能,约定了实现类应该要实现的功能

3.接口的思想——“封装隔离”

4.使用接口的好处

只要接口不变,内部实现的变化就不会影响到外部应用,从而使得系统更加灵活,具有更好的扩展性和可维护性

5.接口和抽象类的选择

(1)优先选用接口

(2)在如下情况选抽象类:既要定义子类的行为,又要为子类提供公共的功能

现在我们再来回答问题三的问题,面向接口编程就是先把客户的业务逻辑线提取出来,作为接口,业务具体实现通过该接口的实现类完成。当用户需求变化时,只需编写该业务逻辑的新实现类接口或通过更改配置文件中该接口的实现类就可以完成需求,不需要改写现有代码,减少对系统的影响。

面向接口编程的优点:

1.减低程序的耦合性,其能够最大限度的解耦,所谓解耦既是解耦合的意思,它和耦合相对。耦合就是联系,耦合越强,联系越紧密。在程序中紧密的联系并不是一件好的事情,因为两种事物之间联系越紧密,你更换中之一的难度就越大,扩展功能和debug的难度也就越大。

2.易于程序的扩展

3.有利于程序的可维护性

通过上面的知识点学习或者回顾,我们来看一段简单的demo1代码

结构图如下:
1.设计模式——工厂模式

我们先看不用模式的解决方案:

代码如下:
1.设计模式——工厂模式

1.设计模式——工厂模式

1.设计模式——工厂模式
运行结果:
1.设计模式——工厂模式

输出的结果从demo1的结构和代码我们可以看出好一个问题:

虽然程序通过new ImplA2()可以正常运行,但是不是真正的面向接口编程。为什么会这样说呢?

首先接口是封装隔离的,但是目前客户端不但知道了接口,而且还知道了内容的实现类是哪个类;

其次客户端直接和接口实现类直接联系了,把接口的诸多好处都丢弃了,无法体现接口的妙处;

最后假设需求发生变更现在“张三要使用Mysql数据库”,我们又该怎么解决?

那我们怎么解决在Java编程中,出现只知接口而不知实现类呢?

这时我们的简单工厂的设计模式就诞生了,我们看一下简单工厂模式的解决方案

简单工厂模式结构图如下:
1.设计模式——工厂模式

我们新加了一个工厂类,去帮我解决该问题,代码如下:

1.设计模式——工厂模式1.设计模式——工厂模式1.设计模式——工厂模式1.设计模式——工厂模式

我们再从客户端的角度看这段程序,首先客户端是通过Factory2.createApi()的方法获得Api2的接口对象的,客户端不知道是哪个实现类实现的,也不知道实现类具体是怎么实现的。达到了客户端只知接口而不知实现类的方式,充分的体现了接口可“插拔”方式(可拓展,易维护)。

那我们再去看“最后假设需求发生变更现在“张三要使用Mysql数据库”"的问题?我可以很好的解决业务扩展的问题了?

我们调整一下代码的结构

1.设计模式——工厂模式

从结构图我们可以看出我们新增了一个ImplB的实现类,该实现类就是我们需要处理业务需求变更的实现

代码
1.设计模式——工厂模式
1.设计模式——工厂模式1.设计模式——工厂模式1.设计模式——工厂模式1.设计模式——工厂模式从上面的代码我们可以看出业务的拓展或者变更,我们只需要新增实现类即可完成。我既可以保证之前的业务代码不动,又能实现业务的拓展。唯一的工作是在工厂里选择具体需要用哪个实现类。

我们再回过头来再重新的认识一下工厂模式

1.简单工厂的功能

可以用来创建的接口、抽象类或者普通类的实例

2.静态工厂

通常把简单工厂类实现成一个工具类,直接使用静态方法就可以了,也就是说简单工厂的方法通常都是静态的,所以也被称为静态工厂

3.万能工厂

一个简单工厂理论上可以用来构造任何对象,所以又称为“万能工厂”

4.简单工厂创建对象的范围

建议控制在一个独立的组件级别或者一个模块级别

5.简单工厂的调用顺序示意图(时序图)
1.设计模式——工厂模式

​6.简单工厂命名的建议

(1)类名建议为“模块名称+Factory”

(2)方法名通常为“get+接口名称”或者是“create+接口名称”

(3)不建议把方法名称命名为“new+接口名称”

可能有朋友会问,工厂该如何选择实现类?通过传参选择,参数又从何而来呢?

1.参数来源于客户端(Client),需要在方法中添加参数,通过参数选择不同的实现类。这种做法会带来一个问题,就是客户端需要知道参数的意思,从某种角度可以理解为实现类在一定程度已经暴露给客户端了,所以这种做法不是最好。

2.参数来源于配置文件​(可配置的工厂)
1.设计模式——工厂模式
1.设计模式——工厂模式 ​注意利用配置文件,可以不用传递参数就可以选择实现类,具体选择是在配置文件配置的(Factory.properties[别名=包路径+实现类名称])。

3.参数来源于系统自身,比如运行期间的某个值

简单工厂的优缺点:

1.帮助封装

2.解耦

3.可能增加客户端的复杂度

4.不方便扩展子工厂

简单工厂的本质:选择实现

何时选用简单工厂:

1.如果想要完成封装隔离具体实现,让外部只能通过接口来操作封装体,那么可以选用简单工厂,让客户端通过工厂来获取相应的接口,而无需关心具体实现

2.如果想要把对外创建的职责集中管理和控制,可以选用简单工厂,一个简单工厂可以创建很多的、不相关的对象,可以把对外创建对象的职责集中到一个简单工厂来,从而实现集中管理和控制。

不好意思哈!水平有限简单工厂目前只介绍这么多哈,如有问题可以相互交流哈!