一、不用模式的解决方案
在java的基础中,通常都是在客户端创建一个Impl实例,把它赋值给一个接口类型的变量,然后客户端就可以通过这个变量来操作接口实现的功能了,其具体的结构图为:
1、代码示例
(1)定义接口Person
(2)定义实现Person
(3)客户端使用
2、存在的问题分析
根据接口的作用和用途,接口的思想就是“封装隔离”,也就是说,外部调用是不知道内部具体实现的,外部调用只能通过接口进行调用。在java编程中,当我们只知道接口而不知道实现,我们该怎么办?
二、使用简单模式解决问题
针对上述问题,虽然不能让模块外部知道模块内部的具体实现,但是我们是可以在内部知道实现的类的,在这里我们引入了简单工厂的概念(在模块内部提供一个创建对象实例的功能,无需关心其具体的实现,被创建实例的类型可以使接口、抽象类和具体是类)。
那么,上述的问题就可以创建一个简单的工厂对象,让简单的工厂来负责创建接口对象,然后让客户端通过工厂来获取接口对象即可,此时系统的结构为:
1、代码示例
(1)接口Person和实现类Student都和前面一样
(2)创建一个简单工厂的对象
(2)使用简单工厂
2、存在问题分析
如果现在实现中,再添加一中实现该怎么办?我们可以在工厂中的方法提供一个参数,当客户需要使用哪个实现时,输入相应的参数,在方法总通过对参数的判断,来选择需要实现的类即可。那么,问题又来了,在客户端我们需要知道每个参数的含义,即需要理解参数对应的处理功能,当参数很多时,这是很麻烦的。另外一个不可避免的问题就是我们需要不断地修改工厂类的方法,这肯定不是一个优秀的现实的。
三、可配置的简单工厂
解决上述问题的一种方法就是使用配置文件,只要在配置文件中配置新的实现类即可,再简单工厂的方法里面可以使用反射,当然也可以使用控制反转或依赖注入来实现。
1、代码示例
(1)配置文件使用最简单的factory.properties文件,定义一个名称为“factory.properties”的配置文件,放置到Factory类的同一个包中,内容如下:
(2)工厂类实现
四、总结
其实我们不难发现,简单工厂的本质是【选择实现】。它非常友好的帮助我们实现了组件的封装,然后让组件外部真正的面向接口编程,并且降低了客户端和具体实现类的耦合度。那么,简单工厂应用的场景是:
(1)如果想要完全封装隔离的具体实现类,让外部只能通过接口来操作封装体。
(2)如果想要把对外创建对象的职责集中管理和控制。