工厂方法模式是创建型模式,基本在学习设计模式的时候,他是比较早被介绍的。但是很多时候也发现,其实根本写不到代码中去,一个原因是使用了spring这种框架后,对象委托spring管理了,另一个原因是这个模式场景是比较特殊的。(本文不是介绍设计模式的,而是探讨模式的适合场景的。)
工厂方法模式的优点
工厂方法模式是管理对象的创建,以及如果有对象改动的时候就可以改掉工厂的内容就可以,而不用改变每个客户端调用的代码。在面对对象创建变更的时候,工厂模式极高内聚了创建过程,修改的时候很方便,对面变化改动量比较小。
为什么使用的场景少
一般情况下,大家写的都是比较简单的javabean,完全直接new就可以,不会特别复杂到创建的时候设置一大堆属性,所以一般写代码不会创建一个类就配一个工厂,这样反而带来了很大的麻烦。稍微麻烦一点的对象,默认优先选择静态工厂,effective java中推荐使用静态工厂替换构造函数。这样方便且满足很大部分的变化。而且我们自己写代码的时候基本遇不到一个类原来是可以new多个的,突然需要变了,要变成单例的情况。所以在很多时候创建对象是比较简单且变动的可能性不会特别大的,稍微想考虑变动这些,也考虑静态工厂。工厂模式在这种情况下显得不合适了。
工作中遇到适合的场景
场景
一个做图的情况,分为设计图形的模块和画图的过程,我的同事负责画图的框架,只要是符合接口的类给他的框架,就可以出结果。我负责去设计图形的形状和样式。
场景分析
我同事这样分割的好处就是达到了解耦的目的,设计图和画图分割,画图的过程其实不需要知道图形的样子,只要给设计好的图形传递过去即可。对于作图的框架,他想解耦,就需要获取设计好的对象,接收一个可以作图的接口和工厂。如何组织这样的接口就需要一个工厂去生产,每个人做的东西都是一个图形模块。每个人只要提供好自己图形模块的工厂就好。
模式适用特点
如上类图,我特意把父类换成了接口,这样更能展示工厂方法的特点,那就是首先得可以去抽象,你可以定义接口去规范一些类,而且调用的地方可以面向接口编程,如果是面向实现类,可能换成建造者模式更好一些。
就如我上面举得例子,调用的地方是面向接口编写的,多个人去实现接口,然后给对应的生产工厂。这样会给开发带来很多好处,起码开发的并行力度更大了,但是工作量小的时候,这样反而是把问题弄复杂了。所以工厂模式需要按照工作量来评估。
总结
工厂方法模式的场景更适合内部已经有一定的框架,为了框架的扩展性,对象接口编程,这时候对象的构建就显得比较重要了,为了维护单一原则,原来的框架一般不会加入对象的构建的细节,所以要使用工厂去担当这个责任,对以后非框架性的替换提供了很多方便,但是同时也需要参考工作量,毕竟工作量比较小,加入一个框架,可能会延误一定的工期。