提供一个/创建/对象实例的/功能,而无需/关心其/具体实现。被/创建实例的/类型可以是接口、抽象类,也可以是/具体的类。
——面向接口编程
不用模式的解决方案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<code>public</code> <code>interface</code> <code>Api {</code>
<code> </code><code>public</code> <code>void</code> <code>product();</code>
<code>}</code>
<code>public</code> <code>class</code> <code>Impl </code><code>implements</code> <code>Api {</code>
<code> </code><code>public</code> <code>void</code> <code>product() {</code>
<code> </code><code>System.out.println(“Now In Impl.“);</code>
<code> </code><code>}</code>
<code>public</code> <code>class</code> <code>Client {</code>
<code> </code><code>public</code> <code>static</code> <code>void</code> <code>main(String[] args) {</code>
<code> </code><code>Api api = </code><code>new</code> <code>Impl();</code>
<code> </code><code>api.product();</code>
使用简单工厂来解决问题
15
16
17
18
19
<code>public</code> <code>class</code> <code>Factory {</code>
<code> </code><code>public</code> <code>static</code> <code>Api createApi() {</code>
<code> </code><code>return</code> <code>new</code> <code>Impl();</code>
<code> </code><code>Api api = Factory.createApi();</code>
在不用模式的解决方案中,你会发现在客户端调用的时候,客户端不但知道了接口,同时还知道了具体的实现就是Impl。接口的思想史“封装隔离”,而实现Impl应该是被Api封装并同客户端隔离开的,也就是说,客户端根本就不应该知道具体的实现类是Impl。
解决思路
分析上面的问题,虽然不能让模块外部/知道/模块内部的具体实现,但模块内部是可以知道/实现类的,而且创建接口是需要/具体实现类的。所以,在模块内部/创建一个类,在这个类里/创建接口,然后把创建好的接口/返回给客户端,这样,外部应用/就只需要根据这个类来获取相应的接口对象,然后就可以操作接口定义的方法了。把这样的对象称为简单工厂,就叫Factory。
应用范围
在Java里,通常情况下/是用来创建接口的,但是也可以创造抽象类,甚至是一个具体的类实例。
静态工厂
使用简单工厂的时候,通常不用/创建简单工厂的类实例。因此简单工厂的方法通常是静态的,所以也称为静态工厂。
如果要防止Client无谓的创建简单工厂示例,还可以把简单工程的构造方法/私有化。
简单工厂调用顺序示意图
<a target="_blank" href="http://blog.51cto.com/attachment/201306/120249139.png"></a>
简单工厂中的方法
简单工厂的方法是:实现了/选择一个合适的实现类来使用,而并不是真的要靠简单工厂来真正实现具体的实现类。
可配置的简单工厂
每次新增加一个实现类都来修改工厂类的实现,肯定不是一个好的实现方法。通过使用配置文件,当有了新的实现类后,只要在配置文件里面配置新的实现类即可。
20
21
22
23
<code> </code><code>Properties p = </code><code>new</code> <code>Properties();</code>
<code> </code><code>InputStream in = </code><code>null</code><code>;</code>
<code> </code><code>try</code> <code>{</code>
<code> </code><code>in = Factory.</code><code>class</code><code>.getResourceAsStream(</code>
<code> </code><code>“FactoryTest.properties”);</code>
<code> </code><code>} </code><code>catch</code><code>(Exception e) {</code>
<code> </code><code>} </code><code>finally</code> <code>{</code>
<code> </code><code>try</code> <code>{</code>
<code> </code><code>in.close();</code>
<code> </code><code>} </code><code>catch</code><code>(Exception e) {</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code> </code><code>//用反射去创建</code>
<code> </code><code>Api api = </code><code>null</code><code>;</code>
<code> </code><code>api = (Api)Class.forName(p.getProperty(</code>
<code> </code><code>“ImplClass”)).newInstance();</code>
简单工厂的优缺点:
优点:帮助封装,解耦
缺点:可能增加客户端的复杂度,不方便扩展子工厂
简单工厂的本质是:选择实现
简单工厂的重点在选择,实现是已经做好了的。就算实现再简单,也要有具体的实现类来实现,而不是在简单工厂里面实现。
简单工厂的目的在于为客户端来选择相应的实现,从而使得客户端和实现之间解耦。
何时选择简单工厂
如果想:封装隔离具体实现,让外部只能通过接口来操作封装体,选用简单工厂,让客户端通过工厂来获取相应的接口,而无须关心具体的实现。
如果想:把对外创建对象的职责集中管理和控制,选用简单工厂,一个简单工厂可以创建很多的、不相关的对象。
本文转自 LinkedKeeper 51CTO博客,原文链接:http://blog.51cto.com/sauron/1223867,如需转载请自行联系原作者