工厂模式
概念
牛马人生公司最近开启了线上直播,直播中牛马人生公司宣称他们建造了一家世界上最为先进的工厂,任何人只要去到工厂面前,告诉工厂你要什么牌子的汽车,工厂就会给你一辆什么牌子的汽车。
这引起了粉丝朋友的注意,纷纷来到工厂一探究竟。
实现步骤
下面我们用代码来表示这个逻辑。
-
牛马人生公司重新定义了汽车的概念,他在幼儿园发出了100份的问卷调查,得到了汽车的定义,以及该拥有的功能。
/*** 汽车的接口定义** @author wanggt* @date 2023-06-17 20:45:27*/ public interface Car {/*** 往前走** @author wanggt* @date 2023-06-17 20:46:21*/void run(); }
-
得到了汽车的最先进的概念之后,牛马人生公司开始设计一个拥有世界上最先进理念的工厂,一家可以制造任何汽车的工厂。在牛马人生公司的设想中,最开始支持的是五菱神车和小鹏汽车。
/*** 汽车工厂类** @author wanggt* @date 2023-06-17 20:51:13*/ public class CarFactory {/*** 在汽车工厂里根据汽车名称提车。** @param name 汽车名称** @author wanggt* @date 2023-06-17 21:00:09*/public static Car getCar(String name) {if ("五菱".equals(name)) {return new WuLingCar();} else if ("小鹏".equals(name)) {return new XiaoPengCar();} else {return null;}} }
-
但是牛马人生公司并不知道汽车的制造方法,所以找到了小鹏和五菱的汽车厂商,学习了汽车的制造技术,以及授权。
/*** 五菱神车** @author wanggt* @date 2023-06-17 20:57:00*/ public class WuLingCar implements Car {@Overridepublic void run() {System.out.println("五菱神车,送货载人都可以,我跑得飞快");} }
/*** 小鹏汽车。** @author wanggt* @date 2023-06-17 20:58:05*/ public class XiaoPengCar implements Car {@Overridepublic void run() {System.out.println("小鹏汽车走啊走");} }
-
粉丝应邀而来,来到工厂前面,果然想要有啥车,工厂就会给啥车。只不过工厂的工程师说,目前工厂支持的车的类型还不多,后面会继续扩展的。
public class SimpleFactoryDemo {public static void main(String[] args) {Car xiaoPengCar = CarFactory.getCar("小鹏");xiaoPengCar.run();System.out.println("===========");Car wuLingCar = CarFactory.getCar("五菱");wuLingCar.run();} }
小鹏汽车走啊走 =========== 五菱神车,送货载人都可以,我跑得飞快
优缺点分析
我们来分析下牛马人生公司的这个工厂。其实他就是使用了简单工厂模式。
优点是:减少了买一辆车的复杂性,我不需要知道汽车里面的构造是怎么样的,也不需要知道什么牌子的汽车就要到哪里去买车。顾客只需要告诉一个名字,这个工厂都可以给客户心目中的汽车。而且未来这个工厂还可以生产越来越多类型的汽车。
缺点呢,工厂的总工程师才不会告诉你,外表看起来光鲜亮丽的汽车工厂,里面是多么的杂乱。因为要制造的汽车类型太多了,每种汽车又有不同的配件。工厂已经不堪重负了。支持的汽车牌子越多,工厂里面就越混乱。
改进方案
日子一天天过去,汽车工厂兼容的汽车类型越来越多,工人们不得不连轴转。而且因为汽车工厂支持的汽车类型太多了,工厂里结构变得异常的复杂。而且性能也越来越低。
新招了一个设计师,刚进到工厂就辞职了。他说他就没有见过这么复杂的结构。
汽车工厂的总工程师想,这么下去可不行啊,全天下有多少汽车类型啊,要是都兼容了,那工厂估计吃不消啊。
于是,在总工程师薅掉了最后一根头发之后,想到了解决办法。
他可以使用工厂方法模式来改造工厂。虽然也是工厂模式,但是工厂方法模式有效避免了修改现有的工厂。可以减少修改,而通过扩展的方式来达到目的。这就是所谓的开闭原则。
总工程师得意地想,姜还是老的辣。
重新设计之后的汽车工厂如下所示:
-
汽车的概念还是一样的。
/*** 汽车的接口定义** @author wanggt* @date 2023-06-17 20:45:27*/ public interface Car {/*** 往前走** @author wanggt* @date 2023-06-17 20:46:21*/void run(); }
-
总工程师增加了一个汽车工厂的设计规范。这里就是跟之前不同的地方。
/*** 汽车工厂类的接口定义。** @author wanggt* @date 2023-06-17 20:51:13*/ public interface CarFactory {/*** 在汽车工厂里根据汽车名称提车。** @author wanggt* @date 2023-06-17 21:00:09*/Car getCar(); }
-
根据汽车的设计规范,打造了一个专门生产五菱神车的工厂。
/*** 汽车工厂类** @author wanggt* @date 2023-06-17 20:51:13*/ public class WuLingCarFactory implements CarFactory {/*** 在汽车工厂里根据汽车名称提车。** @author wanggt* @date 2023-06-17 21:00:09*/@Overridepublic Car getCar() {return new WuLingCar();} }
/*** 五菱神车** @author wanggt* @date 2023-06-17 20:57:00*/ public class WuLingCar implements Car {@Overridepublic void run() {System.out.println("五菱神车,送货载人都可以,我跑得飞快");} }
-
同样,又打造了一个小鹏汽车的工厂。
/*** 汽车工厂类** @author wanggt* @date 2023-06-17 20:51:13*/ public class XiaoPengCarFactory implements CarFactory {/*** 在汽车工厂里根据汽车名称提车。** @author wanggt* @date 2023-06-17 21:00:09*/@Overridepublic Car getCar() {return new XiaoPengCar();} }
/*** 小鹏汽车。** @author wanggt* @date 2023-06-17 20:58:05*/ public class XiaoPengCar implements Car {@Overridepublic void run() {System.out.println("小鹏汽车走啊走");} }
-
粉丝听闻汽车工厂大改造,又来到汽车工厂来围观。发现了汽车工厂的似乎比以前要复杂了,还需要知道小鹏汽车工厂,五菱汽车工厂。纷纷有些不满,但总算还在意料之内。
public class FactoryMethodDemo {public static void main(String[] args) {XiaoPengCarFactory xiaoPengCarFactory = new XiaoPengCarFactory();Car xiaoPengCar = xiaoPengCarFactory.getCar();xiaoPengCar.run();System.out.println("===========");WuLingCarFactory wuLingCarFactory = new WuLingCarFactory();Car wuLingCar = wuLingCarFactory.getCar();wuLingCar.run();} }
-
总工程师松了一口气,以后总算不用担心兼容新的汽车了。只要新建一个对应的工厂就可以生产新的汽车了。
可以看出来,简单工厂模式胜在简单,一个工厂类,一个静态方法就可以获取各种对象。工厂方法模式扩展性比较强,而且满足开闭原则。
选择使用哪一个,主要是看简单不简单。