<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    dream.in.java

    能以不變應(yīng)萬變是聰明人做事的準(zhǔn)則。萬事從小事做起,積累小成功,問鼎大成功,是成功者的秘訣。

    java 設(shè)計(jì)工廠模式[1]

    http://hi.baidu.com/wxl543/blog/item/0e33c0c84acde21f7e3e6f29.html
    一、引子
                 話說十年前,有一個(gè)暴發(fā)戶,他家有三輛汽車——Benz 奔馳、Bmw寶馬、Audi奧迪,還雇了司機(jī)為他開車。
                正在裝載數(shù)據(jù)……
          不過,暴發(fā)戶坐車時(shí)總是怪怪的:上Benz車后跟司機(jī)說“開奔馳車!”,坐上Bmw后他說“開寶馬車!”,坐上Audi說“開奧迪車!”。你一定說:這人有??!直接說開車不就行了?!
                
          而當(dāng)把這個(gè)暴發(fā)戶的行為放到我們程序設(shè)計(jì)中來時(shí),會(huì)發(fā)現(xiàn)這是一個(gè)普遍存在的現(xiàn)象。幸運(yùn)的是,這種有病的現(xiàn)象在OO(面向?qū)ο螅┱Z言中可以避免了。下面就以Java語言為基礎(chǔ)來引入我們本文的主題:工廠模式。

          二、分類
                工廠模式主要是為創(chuàng)建對(duì)象提供過渡接口,以便將創(chuàng)建對(duì)象的具體過程屏蔽隔離起來,達(dá)到提高靈活性的目的。
          工廠模式在《Java與模式》中分為三類:
                 1)簡(jiǎn)單工廠模式(Simple Factory)
          2)工廠方法模式(Factory Method)
          3)抽象工廠模式(Abstract Factory)
                 這三種模式從上到下逐步抽象,并且更具一般性。
                 GOF在《設(shè)計(jì)模式》一書中將工廠模式分為兩類:工廠方法模式(Factory Method)與抽象工廠模式(Abstract
          Factory)。將簡(jiǎn)單工廠模式(Simple Factory)看為工廠方法模式的一種特例,兩者歸為一類。
          兩者皆可,在本文使用《Java與模式》的分類方法。下面來看看這些工廠模式是怎么來“治病”的。
          三、簡(jiǎn)單工廠模式
          簡(jiǎn)單工廠模式又稱靜態(tài)工廠方法模式。重命名上就可以看出這個(gè)模式一定很簡(jiǎn)單。它存在的目的很簡(jiǎn)單:定義一個(gè)用于創(chuàng)建對(duì)象的接口。
                 先來看看它的組成:
          1)        工廠類角色:這是本模式的核心,含有一定的商業(yè)邏輯和判斷邏輯。在java中它往往由一個(gè)具體類實(shí)現(xiàn)。
          2)        抽象產(chǎn)品角色:它一般是具體產(chǎn)品繼承的父類或者實(shí)現(xiàn)的接口。在java中由接口或者抽象類來實(shí)現(xiàn)。
          3)        具體產(chǎn)品角色:工廠類所創(chuàng)建的對(duì)象就是此角色的實(shí)例。在java中由一個(gè)具體類實(shí)現(xiàn)。
          那么簡(jiǎn)單工廠模式怎么來使用呢?我們就以簡(jiǎn)單工廠模式來改造暴發(fā)戶坐車的方式——現(xiàn)在暴發(fā)戶只需要坐在車?yán)飳?duì)司機(jī)說句:“開車”就可以了。


          //抽象產(chǎn)品角色
          public interface Car{
          public void drive();
          }
          //具體產(chǎn)品角色
          public class Benz implements Car{
          public void drive() {
          System.out.println("Driving Benz ");
          }
          }
          public class Bmw implements Car{
          public void drive() {
          System.out.println("Driving Bmw ");
          }
          }
          。。。(奧迪我就不寫了:P)

          //工廠類角色
          public class Driver{
          //工廠方法.注意 返回類型為抽象產(chǎn)品角色
                 public static Car driverCar(String s)throws Exception    {
                        //判斷邏輯,返回具體的產(chǎn)品角色給Client
                        if(s.equalsIgnoreCase("Benz"))  
                               return new Benz();
                        else if(s.equalsIgnoreCase("Bmw"))
                               return new Bmw();
                              ......  
                       else throw new Exception();
                 。。。

          //歡迎暴發(fā)戶出場(chǎng)......
          public class Magnate{
                 public static void main(String[] args){
                        try{
                              //告訴司機(jī)我今天坐奔馳             
                               Car car = Driver.driverCar("benz");
                              //下命令:開車                  
                               car.drive();
                        。。。
              將本程序空缺的其他信息填充完整后即可運(yùn)行。如果你將所有的類放在一個(gè)文件中,請(qǐng)不要忘記只能有一個(gè)類被聲明為public。本程序在jdk1.4
          下運(yùn)行通過。
          這便是簡(jiǎn)單工廠模式了。怎么樣,使用起來很簡(jiǎn)單吧?那么它帶來了什么好處呢?
               
          首先,使用了簡(jiǎn)單工廠模式后,我們的程序不在“有病”,更加符合現(xiàn)實(shí)中的情況;而且客戶端免除了直接創(chuàng)建產(chǎn)品對(duì)象的責(zé)任,而僅僅負(fù)責(zé)“消費(fèi)”產(chǎn)品(正如暴發(fā)戶所為)。

                
          下面我們從開閉原則(對(duì)擴(kuò)展開放;對(duì)修改封閉)上來分析下簡(jiǎn)單工廠模式。當(dāng)暴發(fā)戶增加了一輛車的時(shí)候,只要符合抽象產(chǎn)品制定的合同,那么只要通知工廠類知道就可以被客戶使用了。所以對(duì)產(chǎn)品部分來說,它是符合開閉原則的;但是工廠部分好像不太理想,因?yàn)槊吭黾右惠v車,都要在工廠類中增加相應(yīng)的業(yè)務(wù)邏輯或者判斷邏輯,這顯然是違背開閉原則的??上攵獙?duì)于新產(chǎn)品的加入,工廠類是很被動(dòng)的。對(duì)于這樣的工廠類(在我們的例子中是為司機(jī)師傅),我們稱它為全能類或者上帝類。
                
          我們舉的例子是最簡(jiǎn)單的情況,而在實(shí)際應(yīng)用中,很可能產(chǎn)品是一個(gè)多層次的樹狀結(jié)構(gòu)。由于簡(jiǎn)單工廠模式中只有一個(gè)工廠類來對(duì)應(yīng)這些產(chǎn)品,所以這可能會(huì)把我們的上帝累壞了,也累壞了我們這些程序員:(
                于是工廠方法模式作為救世主出現(xiàn)了。


          四、工廠方法模式
                
          工廠方法模式去掉了簡(jiǎn)單工廠模式中工廠方法的靜態(tài)屬性,使得它可以被子類繼承。這樣在簡(jiǎn)單工廠模式里集中在工廠方法上的壓力可以由工廠方法模式里不同的工廠子類來分擔(dān)。

          你應(yīng)該大致猜出了工廠方法模式的結(jié)構(gòu),來看下它的組成:
          1)        抽象工廠角色:
          這是工廠方法模式的核心,它與應(yīng)用程序無關(guān)。是具體工廠角色必須實(shí)現(xiàn)的接口或者必須繼承的父類。在java中它由抽象類或者接口來實(shí)現(xiàn)。
          2)        具體工廠角色:它含有和具體業(yè)務(wù)邏輯有關(guān)的代碼。由應(yīng)用程序調(diào)用以創(chuàng)建對(duì)應(yīng)的具體產(chǎn)品的對(duì)象。
          3)        抽象產(chǎn)品角色:它是具體產(chǎn)品繼承的父類或者是實(shí)現(xiàn)的接口。在java中一般有抽象類或者接口來實(shí)現(xiàn)。
          4)        具體產(chǎn)品角色:具體工廠角色所創(chuàng)建的對(duì)象就是此角色的實(shí)例。在java中由具體的類來實(shí)現(xiàn)。
          工廠方法模式使用繼承自抽象工廠角色的多個(gè)子類來代替簡(jiǎn)單工廠模式中的“上帝類”。正如上面所說,這樣便分擔(dān)了對(duì)象承受的壓力;而且這樣使得結(jié)構(gòu)變得靈活起來——當(dāng)有新的產(chǎn)品(即暴發(fā)戶的汽車)產(chǎn)生時(shí),只要按照抽象產(chǎn)品角色、抽象工廠角色提供的合同來生成,那么就可以被客戶使用,而不必去修改任何已有的代碼。可以看出工廠角色的結(jié)構(gòu)也是符合開閉原則的!

                
          我們還是老規(guī)矩,使用一個(gè)完整的例子來看看工廠模式各個(gè)角色之間是如何來協(xié)調(diào)的。話說暴發(fā)戶生意越做越大,自己的愛車也越來越多。這可苦了那位司機(jī)師傅了,什么車它都要記得,維護(hù),都要經(jīng)過他來使用!于是暴發(fā)戶同情他說:看你跟我這么多年的份上,以后你不用這么辛苦了,我給你分配幾個(gè)人手,你只管管好他們就行了!于是,工廠方法模式的管理出現(xiàn)了。代碼如下:

          //抽象產(chǎn)品角色,具體產(chǎn)品角色與簡(jiǎn)單工廠模式類似,只是變得復(fù)雜了些,這里略。
          //抽象工廠角色
          public interface Driver{
                 public Car driverCar();
          }
          public class BenzDriver implements Driver{
                 public Car driverCar(){
                        return new Benz();
                 }
          }
          public class BmwDriver implements Driver{
                 public Car driverCar()   {
          return new Bmw();
                 }
          }
          //應(yīng)該和具體產(chǎn)品形成對(duì)應(yīng)關(guān)系...
          //有請(qǐng)暴發(fā)戶先生
           public class Magnate
          {
                        public static void main(String[] args)
                        {
                               try{
                                      Driver driver = new BenzDriver();
                                      Car car = driver.driverCar();
                                      car.drive();
                               }
                 ……
          }
          可以看出工廠方法的加入,使得對(duì)象的數(shù)量成倍增長。當(dāng)產(chǎn)品種類非常多時(shí),會(huì)出現(xiàn)大量的與之對(duì)應(yīng)的工廠對(duì)象,這不是我們所希望的。因?yàn)槿绻荒鼙苊膺@種情況,可以考慮使用簡(jiǎn)單工廠模式與工廠方法模式相結(jié)合的方式來減少工廠類:即對(duì)于產(chǎn)品樹上類似的種類(一般是樹的葉子中互為兄弟的)使用簡(jiǎn)單工廠模式來實(shí)現(xiàn)。

          五、小結(jié)
          工廠方法模式仿佛已經(jīng)很完美的對(duì)對(duì)象的創(chuàng)建進(jìn)行了包裝,使得客戶程序中僅僅處理抽象產(chǎn)品角色提供的接口。那我們是否一定要在代碼中遍布工廠呢?大可不必。也許在下面情況下你可以考慮使用工廠方法模式:

          1)        當(dāng)客戶程序不需要知道要使用對(duì)象的創(chuàng)建過程。
          2)        客戶程序使用的對(duì)象存在變動(dòng)的可能,或者根本就不知道使用哪一個(gè)具體的對(duì)象。
          簡(jiǎn)單工廠模式與工廠方法模式真正的避免了代碼的改動(dòng)了?沒有。在簡(jiǎn)單工廠模式中,新產(chǎn)品的加入要修改工廠角色中的判斷語句;而在工廠方法模式中,要么將判斷邏輯留在抽象工廠角色中,要么在客戶程序中將具體工廠角色寫死(就象上面的例子一樣)。而且產(chǎn)品對(duì)象創(chuàng)建條件的改變必然會(huì)引起工廠角色的修改。

                 面對(duì)這種情況,Java的反射機(jī)制與配置文件的巧妙結(jié)合突破了限制——這在Spring中完美的體現(xiàn)了出來。
          六、抽象工廠模式
                先來認(rèn)識(shí)下什么是產(chǎn)品族: 位于不同產(chǎn)品等級(jí)結(jié)構(gòu)中,功能相關(guān)聯(lián)的產(chǎn)品組成的家族。還是讓我們用一個(gè)例子來形象地說明一下吧。
          可以說,抽象工廠模式和工廠方法模式的區(qū)別就在于需要?jiǎng)?chuàng)建對(duì)象的復(fù)雜程度上。而且抽象工廠模式是三個(gè)里面最為抽象、最具一般性的。
          抽象工廠模式的用意為:給客戶端提供一個(gè)接口,可以創(chuàng)建多個(gè)產(chǎn)品族中的產(chǎn)品對(duì)象
          而且使用抽象工廠模式還要滿足一下條件:
          1)        系統(tǒng)中有多個(gè)產(chǎn)品族,而系統(tǒng)一次只可能消費(fèi)其中一族產(chǎn)品。
          2)        同屬于同一個(gè)產(chǎn)品族的產(chǎn)品以其使用。
          來看看抽象工廠模式的各個(gè)角色(和工廠方法的如出一轍):
          1)        抽象工廠角色:
          這是工廠方法模式的核心,它與應(yīng)用程序無關(guān)。是具體工廠角色必須實(shí)現(xiàn)的接口或者必須繼承的父類。在java中它由抽象類或者接口來實(shí)現(xiàn)。
          2)        具體工廠角色:它含有和具體業(yè)務(wù)邏輯有關(guān)的代碼。由應(yīng)用程序調(diào)用以創(chuàng)建對(duì)應(yīng)的具體產(chǎn)品的對(duì)象。在java中它由具體的類來實(shí)現(xiàn)。
          3)        抽象產(chǎn)品角色:它是具體產(chǎn)品繼承的父類或者是實(shí)現(xiàn)的接口。在java中一般有抽象類或者接口來實(shí)現(xiàn)。
          4)        具體產(chǎn)品角色:具體工廠角色所創(chuàng)建的對(duì)象就是此角色的實(shí)例。在java中由具體的類來實(shí)現(xiàn)。
          
           看過了前兩個(gè)模式,對(duì)這個(gè)模式各個(gè)角色之間的協(xié)調(diào)情況應(yīng)該心里有個(gè)數(shù)了,我就不舉具體的例子了。只是一定要注意滿足使用抽象工廠模式的條件哦。

    posted on 2009-04-05 00:20 YXY 閱讀(123) 評(píng)論(0)  編輯  收藏


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 在线免费视频一区二区| 青青青国产在线观看免费网站| 日韩免费视频网站| 一出一进一爽一粗一大视频免费的| 亚洲日韩在线观看免费视频| 国产成人免费a在线资源| 亚洲色成人四虎在线观看| 国产在线a免费观看| 亚洲美女中文字幕| 日韩在线视频播放免费视频完整版| 日本一区午夜艳熟免费| 亚洲乱码精品久久久久..| 香蕉免费一级视频在线观看| 亚洲一区爱区精品无码| 久操视频在线免费观看| 亚洲国产精品不卡在线电影| 久9热免费精品视频在线观看| 亚洲免费人成在线视频观看| 伊人免费在线观看高清版| 亚洲国产精品久久久久婷婷老年| 久久国产精品成人免费| 亚洲综合区图片小说区| 免费精品国产自产拍在| 亚洲美国产亚洲AV| 99久在线国内在线播放免费观看| 亚洲日韩中文字幕天堂不卡| 一个人看www在线高清免费看| 亚洲AV成人片无码网站| 国产亚洲午夜高清国产拍精品| a级片免费在线播放| 亚洲国产亚洲片在线观看播放| 成熟女人特级毛片www免费| 男女猛烈xx00免费视频试看| 亚洲中文久久精品无码ww16| 120秒男女动态视频免费| youjizz亚洲| 亚洲小说区图片区另类春色| 国产免费的野战视频| 成a人片亚洲日本久久| 亚洲人成色777777在线观看| 99久久99久久精品免费看蜜桃|