享受代码,享受人生

SOA is an integration solution. SOA is message oriented first.
The Key character of SOA is loosely coupled. SOA is enriched
by creating composite apps.
posts - 213, comments - 2315, trackbacks - 162, articles - 45
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

你了解创建者模式了吗? --- 创建者模式详解

Posted on 2005-04-14 23:36  idior  阅读(...)  评论(... 编辑 收藏

你了解创建者模式了吗?

 

我准备从How Why 这两个角度来谈谈我对创建者模式的理解.

 

How to implement Factory and Abstract Factory

 

对于创建者模式, 有一点很容易被大多数人所忽视所误解, 就是Factory模式和Abstract Factory模式的区别.

他们的最重要的区别不是在于Abstract Factory是用于创建产品族, Factory仅仅用于创建一种类型的产品.

他们的区别在于一个很重要的思想: 是采用聚合还是继承? Favor Composition than inheritance.

谈到创建者模式大家不自然的就会想到他们的任务都是用于创建对象. 然而真是这样吗? 他们仅仅是用于创建对象?

让我们来看看Gof书中有关Factory的一个例子


注意到了吗
? Application就是一个Factory, 对于不同的Document我们需要扩展不同的Application然后override它们的CreateDocument方法. 然而Application仅仅是创建文档对象吗? 它还做了一系列的工作,将新建的文档对象添加到文档列表并打开文档. 并且还提供了一个完全和创建无关的打开文档(OpenDocument方法)的功能. 看看它和你想象中的创建者模式一样吗? 它可不是仅仅new 一个对象那么简单. 你注意到了吗? 我估计很多人都没有注意到这点, 甚至在吕震宇的文章中.(吕兄可别怪我 :P 谁叫你太有名了)

 
吕震宇文中的例图

我们只看到了
factory方法. 然而在Gof中的图是这样的:


注意到那个
AnOperation() 了吗?

 

再来看看GofFactory模式的评价:

There are two common ways to parameterize a system by the classes of objects it creates. One way is to subclass the class that creates the objects; this corresponds to using the Factory Method  pattern. The main drawback of this approach is that it can require creating a new subclass just to change the class of the product. Such changes can cascade. For example, when the product creator is itself created by a factory method, then you have to override its creator as well.

 

因为Factory模式不仅仅是创建一个对象那么简单,通常还要加上对创建出来的对象做一些操作(比如初始化一些对象的一些属性, 把对象和环境关联起来)  这样就算那些操作不变仅仅是因为创建的对象变了,你就需要新建一个Factory.

 

For example, when the product creator is itself created by a factory method, then you have to override its creator as well.

这句话有点让人费解,让我们把这句话的演示一下:



Gof
的意思大概如图所示.就是说仅仅是因为文档变了我们不仅要为它造一个老爸(MyApp),还要连带为它造一个爷爷(MyAppCreator).怎样才能不造爷爷?使用Abstract Factory.

这时的工厂就完全是为了创建一个新的对象, 而不在工厂中对新建的对象做任何操作.如下图所示:

 

AppCreator appc=new AppCreator(); 

Application app
=appCreator.Creat(new MyDocCreator()); 

app.NewDoc(); 

将创建对象的功能(DocCreator)从对象的其他操作中(Application)完全分离出来作为一个类, 这样我们就不需要为每种类型的文档造爷爷了.

这个是什么模式?

看看Gof的原话

The other way to parameterize a system relies more on object composition: Define an object that's responsible for knowing the class of the product objects, and make it a parameter of the system. This is a key aspect of the Abstract Factory, Builder, and Prototype  patterns. All three involve creating a new "factory object" whose responsibility is to create product objects.

 

可以发现Factory Vs Abstract Factory  à   Inheritance Vs Composition

 

最后再来谈谈Why?

 

Why do we need Creator pattern? 
 

相信很多初学者会有这么一个问题, 为什么我们需要创建者模式?

然而很多人在向别人介绍创建者模式的时候, 常常对于这个问题一带而过.(比如我的老师).

 

回答: 创建者模式是用来创建对象的模式. 而模式是前人经验的总结,所以创建者模式是一个好东西.

 

Do you need answer like this? What can we learn about Creator Pattern From this ?

首先对我来说这不是我需要的答案, 并且从中我也仅仅知道了创建者模式是用来创建对象的模式. (, 你读读这句话不是废话嘛)

 

那么我的答案是什么?

 

用代码说明问题. (源代码有时胜过千言万语)

 

首先创建了一辆奔驰.

Car car=new Benze();

突然我们的车变了, 变成宝马了. Ok 我修改一下.

Car car=new BMW();

 

设想一下在我们的代码中散布了无数这样的代码.不止一处(这点很重要)

那么当你以后需要换车的时候, 是不是需要一一修改我们的创建代码把Benze改成BMW.

 

然后我们再用工厂来实现一下:

Car car=benzeFactory().Factory();

呵呵 这算什么? 没事找事做. 如果要换车,你不是还要修改原来的代码改成下面这样.

Car car=bmwFactory().Factory();

 

是吗?

如果创建代码只有这里一处可能是这样, 但是如果很多地方都要创建的话就不是了.

 

CarFactory carFac=new BenzeFactory();

 

Car car=carFac.Factory();

当你需要换Car的时候你只需修改一处代码就是CarFactory carFac=new XXXFactory();

其他创建车的地方,永远不变,还是Car car=carFac.Factory();

Ok? 你明白了吗?

我们很难避免修改, 但是我们要尽量做到只修改一处.

 

不知道 这样的解释你是否满意.

使用创建者模式是为了提高代码的可维护性(即应对未来修改的能力).