小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

JR - 精品文章 - 設(shè)計(jì)模式入門之一 工廠方法

 不會(huì)游泳的魚 2006-06-18
設(shè)計(jì)模式入門之一
DenialSu 轉(zhuǎn)貼  (參與分:31140,專家分:3808)   發(fā)表:2005-12-12 10:58   版本:1.0   閱讀:865

開宗明義
話說設(shè)計(jì)模式以來,眾人皆奉為經(jīng)典,其實(shí)說穿了不過是一個(gè)矛盾的辯證關(guān)系而已,即如
何將變化與固定相統(tǒng)一的問題。通常的代碼是固定的,很難變化;
而需求與環(huán)境是變化的,故而兩者是矛盾的。但我們卻要在程序中將兩者的矛盾處理好。
然而,兩者又是統(tǒng)一的,因?yàn)樽兓褪菫榱?#8220;不變”,即最大限度地重用已有的“不變”
代碼;另一方面,將“不變”認(rèn)識(shí)清楚,就知道哪些該“變化”,哪些該讓它“變化”。
只有在固定的基礎(chǔ)上,將該變化的讓它變化,程序才能既牢固,又有彈性,從而能夠滿足
各方面的要求。后面的分析過程,希望大家能夠牢記這個(gè)要點(diǎn),從這個(gè)角度來看設(shè)計(jì)模式
,而不是為學(xué)模式而學(xué)模式,那樣我認(rèn)為永遠(yuǎn)都沒有自己的領(lǐng)悟。而且設(shè)計(jì)模式也不是固
定的,隨著時(shí)間的推移會(huì)出現(xiàn)其它的新模式,但我想仍然是符合”變化與固定“這個(gè)原則
的。
好了,羅嗦了這么多,我們首先從常見的《創(chuàng)建型模式》說起,我首先不給出干巴巴的定
義,而是給出活生生的例子,從實(shí)踐出總結(jié)出規(guī)律,再給出定義就是水到渠成的事情了。


迷宮是許多游戲的組成元素,玩家在迷宮時(shí)探索,從一個(gè)入口進(jìn)入迷宮,在迷宮中穿行,
與遇到的敵人激戰(zhàn),撿取醫(yī)藥包、武器等物品,最后找到出口,其間經(jīng)常從一個(gè)房間進(jìn)入
另一個(gè)房間,碰了壁就走過其它的路,如此反復(fù)。姑且不考慮這么復(fù)雜,我們現(xiàn)在僅關(guān)心


迷宮的創(chuàng)建。遵循著“將問題簡(jiǎn)化到不能簡(jiǎn)化”的原則,我們假設(shè)此迷宮中僅有兩個(gè)房間
和一扇門,從其中一個(gè)房間推開門就可以進(jìn)入另一個(gè)房間。整個(gè)迷宮的坐標(biāo)是二維的,即
使用“東南西北”作為方位。
我們首先大致寫出迷宮中房間、門、墻的框架,再接著我們的討論(我們使用MapSite作為
所有組件的協(xié)議接口):
interface MapSite {
    public void enter();
}

class Room implements MapSite {
    public Room(int roomNo) {
        this.roomNo = roomNo;
    }

    public void enter() {
    }

    public MapSite getSide(int n) {
        return _sides[n];
    }

    public void setSide(int n,MapSite ms) {


        _sides[n] = ms;
    }
}

class Wall implements MapSite {
    public Wall() {
    }

    public void enter() {
    }
}

class Door implements MapSite {
    public Door(Room r1,Room r2) {
        _room1 = r1;
        _room2 = r2;
    }

    public void ener() {
    }
}



//迷宮類
class Maze {
    public Maze() {
    }

    public void addRoom(Room r) {
    }

    public Room roomNo(int) {
    }
}

有了磚瓦,就可以蓋房子了。我們利用這些原料來搭建一個(gè)迷宮。我們能想到的最自然、
最簡(jiǎn)單的方法,就是在迷宮游戲類的一個(gè)方法中寫下創(chuàng)建代碼:
class MazeGame {
    public Maze createMaze() {
        Maze aMaze = new Maze();
        Room r1 = new Room(1);
        Room r2 = new Room(2);
        Door theDoor = new Door(r1,r2);

        aMaze.addRoom(r1);


        aMaze.addRoom(r2);

        r1.setSide(North,new Wall());
        r1.setSide(East,theDoor);
        r1.setSide(South,new Wall());
        r1.setSide(West,new Wall());

        r2.setSide(North,new Wall());
        r2.setSide(East,new Wall());
        r2.setSide(South,new Wall());
        r2.setSide(West,theDoor);

        return aMaze;
    }
}
在createMaze的代碼中,我們寫下了迷宮構(gòu)成部件的生成代碼和迷宮本身的布局代碼。那
么,我們從“變與不變的角度”可以知道,整個(gè)代碼部分都是可以變化的.
大家好好想一想,一個(gè)游戲可能會(huì)升級(jí),今天的一個(gè)房間里可能是一個(gè)醫(yī)藥包,明天可能
你得要鑰匙才能打開這個(gè)門取得這個(gè)醫(yī)藥包,后來還有可能是其它什么東東。
這么多哇?!別急,我們還知道,今天,這個(gè)迷宮的地圖是這樣,明天可能是那樣,后天
。。。打住,讀者可能頭都大了,你改來改去我的代碼不是成馬蜂窩了嗎?
我的代碼是死的,怎么可能一會(huì)兒是這個(gè),一會(huì)兒是那個(gè),不是要我命嗎?嘿嘿,別急,


我們要承認(rèn)這樣一個(gè)事實(shí)。[需求是不斷改變的],正如馬原所講[運(yùn)動(dòng)是絕對(duì)的,靜止是相
對(duì)的],只有正視這個(gè)問題,我們才能開發(fā)出合乎要求的軟件來。我決定對(duì)這個(gè)問題按兩個(gè)
方面來討論,首先解決迷宮中的門變化的問題,后面的文章再討論迷宮的布局變化的問題
,必竟,飯要一口一口吃嗎!

請(qǐng)大家思考一下,上面的代碼要怎樣才能滿足變化的需要呢?首先,我們承認(rèn),代碼只有
變化,才能反映要求的變化,只是如何變化才巧妙而已。在程序代碼中,虛方法是變化的
不二法門。為什么這么說呢?
因?yàn)樘摲椒梢宰屇阍?#8220;不變”的基礎(chǔ)上達(dá)到“變化”的目的。不是嗎?所有的OO教材上
都把這一點(diǎn)作為OO的頭一優(yōu)點(diǎn)來大書特書,我們也來這樣操作一番??墒?,我要變化的創(chuàng)
建房子、墻、門,這些不可能改變呀,因?yàn)槌跏蓟恼Z法就限制了你必須使用構(gòu)造方法名
,而構(gòu)造方法名與類名是相同的,你要改變成另一個(gè)類,就必須在迷宮創(chuàng)建代碼中將名稱
改變成新類的名稱。
OK,我們找到了問題的所在,我們要改變創(chuàng)建的類,而上面的代碼不讓我們改變,這是語
言限制,我們只要找一種既能創(chuàng)建自己的對(duì)象又能無需改變創(chuàng)建代碼的方法。沒關(guān)系,我
在這個(gè)迷宮代碼中非要使用構(gòu)造器來創(chuàng)建一個(gè)類的對(duì)象嗎?
不用,雖然本質(zhì)上我們最終還是要使用創(chuàng)建語法,但在上面的代碼中,我們完全不用這么
做?我們代之以虛方法?
Room createRoom(int roomNo) {
    return new Room(roomNo);
}
代入上面的代碼后,變?yōu)?br>

Room r1 = createRoom(1);
Room r2 = createRoom(2);
如果再有新的房子出來,只要提供另一個(gè)createRoom的實(shí)現(xiàn),上面的代碼只要布局不變,
是不用改變的,不是嗎?OK!
只是,在OO中,所有的方法都應(yīng)該是成員方法或類方法,上面的方法是哪個(gè)類的呢?顯然
,我們可以將createRoom作為MazeGame的成員方法。于是,我們又有了createWall和crea
teDoor方法,要改變創(chuàng)建的東西,我們只要繼承MazeGame,
重寫createXXX方法,不就達(dá)到了“不變”的目的嗎?下面是新的MazeGame的代碼:
class MazeGame {
    public MazeGame() {
    }

    public Room createRoom(int roomNo) {
        return new Room(roomNo);
    }

    public Wall createWall() {
        return new Wall();
    }

    public Door createDoor(Room r1,Room r2) {
        return new Door(r1,r2);


    }

    public Maze createMaze() {
        //ommit here
    }
}

到此為止,大家學(xué)會(huì)了一種簡(jiǎn)單實(shí)用的設(shè)計(jì)模式,即Factory Method,希望大家再接再厲
,跟我一起來了解一下Factory Method的理論,畢竟實(shí)踐清楚了,就要上升到理論高度,
同意嗎?
冷靜地分析一下,問題的關(guān)鍵在MazeGame類,此類預(yù)留了若干個(gè)接口,讓子類通過重寫這
些接口,來達(dá)到實(shí)例化“具體的類”,這些“具體的類”用來構(gòu)成Maze類。
這個(gè)框架能夠改變類的實(shí)體,但無法改變類之間的組合關(guān)系(這應(yīng)是本方法的缺點(diǎn))。再
來看,我們是將具體的創(chuàng)建Room、Wall、Door的操作抽象成對(duì)應(yīng)的方法,使得創(chuàng)建與其他
代碼隔離,達(dá)到重用這些其他代碼的目的。這也是“創(chuàng)建型模式”的名稱由來。

MazeGame有許多的接口,可以完成創(chuàng)建組成對(duì)象的工作,我們稱之為“工廠”,工廠中創(chuàng)
建對(duì)象的方法,我們稱之為“工廠方法”。
通過在具體的工廠中,重寫工廠方法,或者說生成具體的工廠方法,生產(chǎn)出具體的產(chǎn)品,
達(dá)到所需的效果,這應(yīng)是“工廠方法”的幾個(gè)要素。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多