GoF设计模式学习笔记(一)---工厂模式

Posted on 2007-05-11 14:56 久城 阅读(2778) 评论(9)  编辑  收藏 所属分类: GOF设计模式

隐喻是一种明智的学习方法。世界上很多深奥的理论都是用隐喻来理解消化的。这是今天早晨看代码大全第一章的感触。

一.抛花引狼
用些生活常识理解一下工厂模式。


那么学习工厂模式,就先来谈谈工厂。什么是工厂呢?这个好像还不应该由我来下定义。我们只需要想一想工厂是什么样的。生活中有很多个工厂。服装制造工厂,汽车制造工厂,等等。都是用来生产产品的。每个工厂都有自己的生产线,销售处等等。

下面结合着头脑中工厂的概念,来认识一下GoF设计模式中的工厂模式。

工厂就用来生产产品的。在我们程序设计过程中,每一个对象的创建,就象是一个产品的诞生。创建一个对象,是为了提供给一个使用者使用的,就象生产一个产品是为了提供给一个消费者使用一样。

我们无时无刻不在调用着new()方法,就象Car car = new Car();然后,一个Car的对象car产生了。这个过程中,我们调用了Car的构造器来产生对象。这样看来,好像并不需要工厂模式来为我们做什么啊?我们再进一步分析一下。现实生活中要买车,不会简简单单的new Car()这样做。至少,我们要明确,买什么类型的车啊?买哪个厂家制造的车啊?买什么价位的车啊?买什么颜色的车啊等等。也许这些,你也可以由Car的构造器通过参数传递来实现。那么再比如,如果价位低于x就买A类型的车,如果价位高于x就买B类型的车。这样也许也可以由构造器进行一次逻辑判断来实现......这样,我们不难发现,问题越复杂的时候,我们的构造器也会变得越来越复杂。这样明显违背了面向对象的封装(Encapsulation)和分派(Delegation)。我们应该将代码分派成一段一段,将每一段再“封装”起来。这样,形成松藕合的状态,以后如果需要修改,只要更改每一段,而不会牵一动百。

那么,我们应该怎么做呢?其实上面的例子已经潜在的告诉我们该怎么做了。我的原则始终是,面向对象,一切从现实中的理论出发,很多都符合生活常识。现实中一个Car是如何产生的呢?这是废话!当然是是由工厂制造出来的。如果只提到工厂,那么很显然,这个名词是抽象的。我们看不到到底是哪家工厂。这样就出现了另一个概念---抽象工厂。我们先不去仔细的理解什么是抽象工厂。还是先研究从现实的角度去看,一个Car是如何被生产的。首先有一个具体的汽车制造工厂。这个汽车制造工厂具有一般工厂都具有的特性。特殊的,它是生产汽车的,也就是在它的内部存在汽车的生产线。同时,工厂里还置有汽车的销售处。用来对工厂外的消费者进行交易的。这样,就产生了几个相应的部门(模块)。

说了半天的废话,让我们先来看个例子。

//我们的工厂
class CarFactory {
    
//这个接口想像成工厂对外的销售处
    public static Car creator(int type) {
        
//这里就来到了汽车的生产线
        if (type == 1)
            
return new Car();
        
else if (type == 2)
            
return new Car2();
    }

}

如果还没有理解为什么要这样写,而不是都封装到Car的构造器里,那就硬记下来吧。因为以后随着项目的深入,对CarFactory的扩张会越来越多。到时候就会体会到这样写的好处了。因为偶也是初次学习。^.^!

所以,以后涉及到一个对象创建的时候,就要考虑一下,是否需要应用一下工厂模式。特别是,对于某些类,类的创建就是类的主要功能。


二.孔孟之道
书接上文,言归正传

上面所讲的无非是一种方法。一种采用工厂的模式来生产产品的方法。我之所以要在这里强调,因为,我们要学习的是这种模式,而不要把模式固定在某些名词上。有可能,工厂,也是一种产品。

现在,抛开现实中的理论(好多大白话),从程序设计的角度去想工厂模式。
工厂模式是创建型模式里面主要的模式之一,它的思想是把类创建的逻辑和过程封装起来,隔离客户端。我们通常创建类的实例都是直接调用其构造方法,这是最常用的方法,但是当类的体系变得复杂,类的创建逻辑变得复杂的时候就需要在客户端使用大量的判断代码,而且使用这些类越多,这样的代码会充斥到系统各个地方。所以把类的创建过程独立开来,用另外的一个类来负责,这就引入了工厂模式。根据这个工厂类的复杂程度,又分为工厂方法和抽象工厂模式。

工厂方法模式(Factory Mehod Pattern)   简单工厂模式,一个工厂生产多个产品;
抽象工厂模式(Abstract Factory Pattern)  更复杂的工厂模式,产生多个工厂;

网上看见有前辈把工厂模式分成三种,还有一个简单工厂模式。我感觉,无所谓。如果让我来写,很有可能就是一种模式,我都叫它抽象工厂模式。只不过在遇到不同程度的问题时。这种模式的使用形式有些变化而已。至少我现在是这样理解的。

那我就接合应用来说一下我理解的工厂模式。

比如,我们要建立一个有XX效果的类Something。这个XX效果会影响到Something的构造过程。原则上讲,XX并不属于Something中的固有属性,只能说XX是Something的一种特殊属性或者是一种特殊效果。我们用工厂模式来构造一下。

首先引入一个工厂接口,此接口定义了Something的创建方法(也可以不定义在这里,在子工厂中实现)。为了生产XX的Something,特别为其实现一个特定的子工厂类。这个子工厂是专门用来生产具有XX效果的Something的。(同样,我们也可以再实现一个子工厂,专门用来生产具有YY效果的Something。)这样就把不同效果的Something创建方法隔离开来。每种效果和Something的构造过程是封装在一起。我们可以根据情况来实现不同效果下的Something。

总之就是不能把创建逻辑放在使用的客户端。就是把创建对象的逻辑过程和使用过程放在一起(也就是放在客户端)。或者说,不要让使用产品的人看见产品是如何产生的。使用者看见的应该只是产品工厂和工厂出售产品的“受付”(销售处)。使用者只要走到工厂的门口,而不要让使用者走到生产线去买东西。为什么这样做呢?想想现实中为什么这样做呢?也许就会理解了。如果一堆人排着大队在生产线旁买东西。生产出一个卖一个。不乱吗?一,对于产品的生产方来说,这样做太危险了,很难预测消费者会无意中对生产线造成多打的影响。而且不方便管理。二,对于使用者来说,也不方便购买。用户希望的就是看到一个销售窗口,我告诉你买什么,你给我什么产品就够了。没必要看见产品是如何产生的。

千万不要让用户到生产线去买东西!会很危险。

三.看图识字
就像小学生学东西一样来理解抽象工厂。


你只说工厂,那给我的感觉就是抽象的。因为我并不知道你说的到底是那家工厂,什么工厂等等。但是,我可以想像到在一个很大的地方,耳边传来轰轰的声音,生产线在工作的情景.......这就是抽象的工厂。

具体的来说,生活中有很多的工厂。比如服装制造工厂,洗涤品制造工厂,汽车制造工厂...他们都是工厂。他们都有自己的产品。而且,单说服装制造工厂,就有很多家...

服装制造工厂的产品有衣服,裤子等。洗涤品制造工厂的产品有洗衣粉,香皂等。从厂家的角度来讲,不同的厂家生产相同或不同的产品。从产品的角度来讲,同样的产品由一个厂家或者多个厂家来生产。这个结构看起来很复杂。所以,我们必须要引入抽象的概念。当一个问题很难用具体的某个实例来描述的时候,我们不妨想想引入抽象

首先是抽象的工厂,具体什么样的工厂有其子工厂去实现。再进一步,也有抽象的产品,具体的产品由其子产品去实现。

举例来说。电脑生产工厂。其子工厂会有联想电脑生产工厂,IBM电脑生产工厂等等。而IBM电脑这个产品,可能也是抽象的。其子产品可以有IBM台式机,IBM笔记本电脑。

如何具体的实现我们的抽象工厂,就要随问题的应用而定。可能世界上只有一种笔记本,可能IBM还生产汽车。没有固定的实例,只有固定的模式

比如:

public abstract class Factory{

  
public abstract product1 creator();

  
public abstract product2 creator2(); 

}


public class FactoryA extends Factory{

  
public product1 creator(){
    
    
return new product1A
  }


  
public product2 creator2(){
    
    
return new product2A
  }

}


public class FactoryB extends Factory{

  
public product1 creator(){
    
    
return new product1B
  }


  
public product2 creator2(){
    
    
return new product2B
  }

}


由此可见,工厂方法确实为系统结构提供了非常灵活强大的动态扩展机制,只要我们更换一下具体的工厂方法,系统其他地方无需一点变换,就有可能将系统功能进行改头换面的变化。

个人理解。随时补充。

 



欢迎来访!^.^!
本BLOG仅用于个人学习交流!
目的在于记录个人成长.
所有文字均属于个人理解.
如有错误,望多多指教!不胜感激!

Feedback

# re: JOF设计模式学习笔记(一)---工厂模式  回复  更多评论   

2007-05-11 15:32 by justin
JOF设计模式?GOF

# re: GOF设计模式学习笔记(一)---工厂模式  回复  更多评论   

2007-05-11 15:52 by 久城
哈哈!失误!多谢提醒!
GoF!Group of Four!~

# re: GoF设计模式学习笔记(一)---工厂模式  回复  更多评论   

2007-05-11 16:30 by Earth
谢谢。希望不久能看到更多点的

# re: GoF设计模式学习笔记(一)---工厂模式  回复  更多评论   

2007-05-11 21:35 by 网路冷眼@BlogJava
@久城
GoF,Gang of Four,请见Gang of Four,到底翻译成是"四人帮"还是"四人组":http://www.blogjava.net/lewhwa/archive/2006/11/05/79161.html

# re: GoF设计模式学习笔记(一)---工厂模式  回复  更多评论   

2007-05-12 12:07 by 久城
@网路冷眼@BlogJava
哦!多谢指教。还真没注意这个地方。一直以为是Group of Four呢!一叫“四人帮”总是让我想起中国的那四个人...

# re: GoF设计模式学习笔记(一)---工厂模式  回复  更多评论   

2007-05-12 14:17 by 网路冷眼@BlogJava
@久城
哈哈,这是老外的幽默

# re: GoF设计模式学习笔记(一)---工厂模式  回复  更多评论   

2007-05-13 17:30 by 快译站
博主, 感觉你的博屋弄的很感觉很漂亮哦,呵呵,文章也写的好,不错

www.doodle8.cn 涂鸦基地,跟踪最新的 web2.0 资源

# re: GoF设计模式学习笔记(一)---工厂模式  回复  更多评论   

2007-05-13 17:30 by 快译站
一看就知道 CSS 高手,呵呵


www.doodle8.cn 涂鸦基地,跟踪最新的 web2.0 资源

# re: GoF设计模式学习笔记(一)---工厂模式  回复  更多评论   

2007-05-14 10:17 by 糖果
我的数据库访问类采用的也是工厂模式,一直都不清楚这个概念.
感觉你的文章我要看懂还有一些难度,我落后太多了,要多努力了。

只有注册用户登录后才能发表评论。


网站导航:
 

Copyright © 久城