天天看点

2.[研磨设计模式笔记]简单工厂 1.定义 2.解决问题 3.模式讲解 4.思考

提供一个/创建/对象实例的/功能,而无需/关心其/具体实现。被/创建实例的/类型可以是接口、抽象类,也可以是/具体的类。

——面向接口编程

不用模式的解决方案

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,如需转载请自行联系原作者