面向接口及单例工厂随笔
面向接口及单例工厂
单例工厂是工厂模式的一种,表示生产出的产品为单例产品。
在上古web开发中,后端是servlet、service、dao这三层。servlet依赖service,service依赖dao,为什么说依赖,因为该层持有另一层的对象:
这里为什么将UserService和UserDao声明为接口,并让其引用实现类呢?
我们要知道的是,Java语言是编译型语言,.java
源代码文件是需要编译成.class
之后才能运行,如果我们需要切换业务模式,比如需要使用UserService2
的业务模式,对于上面用new
的方式去创建对象,我们就需要去修改源代码,然后重新编译才能运行。而在项目大的时候,编译是非常耗费时间的。
对于时间就是金钱的互联网行业,在你编译的时候,你的对手可能就把你的顾客给抢走了,那么有没有一种方法可以快速切换呢?
有,就是使用反射 + 配置文件
的方式来获取对象,当需要不同的对象时只需要修改配置文件,而不用重新编译:
service.properties文件:
这样当我们想获取不同的UserServiceImpl实例时只需要修改配置文件并重启服务器即可。
这也是为什么上面使用接口引用其实现类,如果直接使用实现类去引用的话则不能达到这种效果。
上面的优化后虽然不用重新编译了,但是问题又来了:除了UserServlet中这样反射获得了一个对象,另一个Servlet中——ProductServlet也需要一个类似的ProductService对象,甚至Service中也需要dao对象,这些代码都很像,那么我们可不可以把这一部分给单独抽取出来,作为工具类使用能?
尝试一下:
我们把这一部分逻辑相似的代码作为一个类的静态方法来使用,这个方法是专门用来生产对象的,我们把这种模式叫做工厂模式。
上面的方式虽然很不错,但还是存在一些问题的:如果不止一个Servlet中需要使用UserService的实现类对象,比如Produce中也需要使用,是不是每个需要使用的地方都要用这种方式持有一个对象呢?
对于每个需要使用到UserService的地方来说,我们只关注UserService中的方法,我们只是想使用它的功能,我们不关注这个对象怎么创建,也不关注是否是同一个对象,如果每个需要使用到的地方都去 getgetInstance来获得一个对象,这样会造成资源的浪费,那么能不能只创建一个对象来供许多地方使用能?
可以,这就是单例工厂:
这样我们获取的的就是同一个对象了。