1. 简单工厂(SimpleFactory)
1)场景问题
在一家生产手机的工厂里,同时生产huaw、meiz和IPhone手机;
车间主任安排了一名监管人员去定时检测各个车间的工人的工作情况。
一般来说,如果主管这么来监管:“好好工作,生产huaw手机啊。”或者“好好工作,生产meiz手机啊”,会不会很别扭?
因为主管不需要问工人生产什么手机,他只需要说“好好工作,生产手机”就行了。
非得让主管知道自己去的车间生产的是什么,是没必要且不符合职业要求的。
2)问题描述
比如我们客户端测试使用Api接口,不能直接使用接口,而是使用接口的实现类Impl。
这样一来,客户端在调用的时候,不但知道了接口,同时还知道了具体的实现就是Impl。接口的思想是“封装隔离”,也就是说客户端不应该知道实现类是Impl。
然而如果把“new Impl()”去掉后,就无法得到Api接口对象了。
也就是说,出现只知道接口而不知实现的情况。
3)解决方案
模式定义:
提供一个创建对象实例的功能,而无需关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类。 |
模式结构:
|
Api:定义客户所需要的功能接口。 Impl:具体实现Api的实现类,可能会有多个。 Factory:工厂,选择合适的实现类来创建Api接口对象。 Client:客户端,通过Factory来获取Api接口对象,然后面向Api接口编程 |
4)示例代码
(1)Api定义的示例代码如下:
/** * 接口的定义,该接口可以通过简单工厂来创建 */ publicinterfaceApi{ /** * 示意,具体功能方法的定义 * @param s示意,需要的参数 */ publicvoidoperation(String s); }
|
(2)定义了接口,接下来实现它。ImplA的示例代码如下:
/** * 接口的具体的实现对象A */ publicclassImplAimplementsApi{ publicvoidoperation(String s){ //实现功能的代码,示意一下 System.out.print("ImplA s=="+s); } }
|
ImplB的示意实现和ImplA基本一样。示例代码如下:
/** * 接口的具体的实现对象B */ publicclassImplBimplementsApi{ publicvoidoperation(String s){ //实现功能的代码,示意一下 System.out.print("ImplB s=="+s); } } |
(3)下面来看看简单工厂的实现。示例代码如下:
/** * 工厂类,用来创建Api对象 */ publicclassFactory{ /** * 具体创建Api对象的方法 * @param condition示意,从外部传入的选择条件 * @return创建好的Api对象 */ publicstaticApicreateApi(int condition){ //应该根据某些条件去选择究竟创建哪一个具体的实现对象 //这些条件可以从外部传入,也可以从其他途径来获取 //示意使用条件 Api api=null; if(condition==1){ api =newImplA(); }elseif(condition==2){ api =newImplB(); } return api; } } |
(4)再来看看客户端的示意,示例代码如下:
/** * 客户端,使用Api接口 */ publicclassClient{ publicstaticvoidmain(String[] args){ //通过简单工厂来获取接口对象 Api api=Factory.createApi(1); api.operation("正在使用简单工厂"); } } |
可知,这个时候,客户端就不用再自己去创建接口的对象了,应该使用工厂来获取。
这样一来,客户端根本不知道具体的实现是什么,也不知道是如何实现的。
只知道通过工厂获得了一个接口对象,然后通过接口来获取想要的功能。
5)优缺评价
优点 ·帮助封装 虽然简单,但是很有好地帮助我们实现了组件的封装。然后让组件外部能真正面向接口编程。 ·解耦 实现了客户端和具体实现类的解耦 |
缺点 ·可能增加客户端的复杂度 如果通过客户端的参数来选择具体的实现类,就必须让客户端能理解各个参数所代表的意义,会增加客户端使用难度,也部分暴露了内部实现,可以选用可配置的方式来解决。 |
6)适用场合
客户端不需要知道具体接口对象的实现意义以及实现方法。
打个比方,一个暴发户同时买了大众、奔驰和宝马,并且为每辆车配备了老司机。
早上出门他随便进一辆车,不需要去看自己做的什么车,然后告诉司机“开大众/奔驰/宝马车”,只需司机自己知道自己开的是什么车怎么开就行,暴发户老板只需要说“开车”就行
7)相关延伸
可配置的简单工厂:
通过配置文件进一步简化客户端的使用,进一步减少内部实现的暴露。