簡(jiǎn)單而有效的深入設(shè)計(jì)模式

每一個(gè)階段,我對(duì)設(shè)計(jì)模式都有不同的理解盒使。

隨著對(duì)函數(shù)式編寫(xiě)的熱愛(ài)艇劫,對(duì)關(guān)系型數(shù)據(jù)庫(kù)和文檔型數(shù)據(jù)庫(kù)的對(duì)比吼驶,我對(duì)設(shè)計(jì)模式又有了新的感覺(jué)。

我覺(jué)得范例總是最有效的說(shuō)明店煞,假設(shè)我們以一個(gè)餐館來(lái)作為對(duì)象(我的英文不怎么樣蟹演,就不要計(jì)較拼寫(xiě)了):

Eatery (餐館類(lèi))

首先,有了一個(gè)餐館類(lèi)顷蟀,然后加上餐館提供的接口酒请,餐館就可以工作了。目前鸣个,先提供:

    milk()                    // 來(lái)份牛奶
    rice()                    // 來(lái)份炒飯

當(dāng)然羞反,還得有餐館建立的時(shí)間、城市囤萤、老板昼窗、雇員、價(jià)格...于是還得加上下面的:

    build_date             // 建立日期
    city                      // 所在城市
    boss_a                  // 老板a
    employee_a           // 雇員a
    employee_b           // 雇員b
    employee_c           // 雇員c
    price_milk              // 牛奶價(jià)格
    price_rice              // 炒飯價(jià)格
    menu_milk             // 牛奶菜單
    menu_rice             // 炒飯菜單

另外涛舍,客人進(jìn)來(lái)餐館澄惊,還要報(bào)價(jià)不是,所以,還得加上:

    get_price()            // 報(bào)價(jià)    

如果要做成程序缤削,還得報(bào)告建立的日期窘哈、城市...所以,還得加上:

    get_build_date()        // 報(bào)告建立日期
    get_city()                 // 報(bào)告所在城市
    get_boss()                // 報(bào)告有哪幾個(gè)老板
    get_employee()          // 報(bào)告有哪幾個(gè)雇員
    get_price()                // 報(bào)告菜品價(jià)格
    get_menu()               // 報(bào)告菜單上的菜

先大致如此吧亭敢,于是,得到了一個(gè)可以使用的餐館了:

Eatery:

    build_date               // 建立日期
    city                        // 所在城市
    boss_a                   // 老板a
    employee_a             // 雇員a
    employee_b             // 雇員b
    employee_c             // 雇員c
    price_milk                // 牛奶價(jià)格
    price_rice                // 炒飯價(jià)格
    menu_milk               // 牛奶菜單
    menu_rice               // 炒飯菜單

    get_build_date()       // 報(bào)告建立日期
    get_city()                // 報(bào)告所在城市
    get_boss()               // 報(bào)告有哪幾個(gè)老板
    get_employee()         // 報(bào)告有哪幾個(gè)雇員
    get_price()               // 報(bào)告菜品價(jià)格
    get_menu()              // 報(bào)告菜單上的菜

    milk()                      // 來(lái)份牛奶
    rice()                      // 來(lái)份炒飯

目前图筹,餐館應(yīng)該是這么運(yùn)作的:

告訴我餐館建立日期 get_build_date()

告訴我餐館所在城市 get_city()

告訴我餐館菜單上的菜 get_menu()

告訴我餐館菜單上的價(jià)格 get_price()

給我來(lái)一個(gè)牛奶 milk()

給我來(lái)一份炒飯 rice()

現(xiàn)在帅刀,先不管面向?qū)ο螅葋?lái)想想關(guān)系型數(shù)據(jù)庫(kù)远剩,要做個(gè)餐館的數(shù)據(jù)庫(kù)該怎么打草稿?

table_eatery:   起個(gè)名字扣溺, 從餐館的基礎(chǔ)來(lái)開(kāi)始吧

    id                           // 現(xiàn)在當(dāng)然只有一個(gè)餐館
    build_date                // 建立日期
    city                        // 所在城市

是不是應(yīng)該是這樣的?

我們總是保持基礎(chǔ)的那個(gè)表格盡可能簡(jiǎn)單高效.

這份表格告訴我們 : 餐館建立日期和所在城市瓜晤,還有通過(guò)id號(hào)能獲取到這個(gè)餐館锥余。

就這么多!

如果想知道餐館的老板怎么辦痢掠?

簡(jiǎn)單驱犹!

建個(gè)表格,show me the info:

table_boss:

    id
    boss_name
    eatery_id

應(yīng)該是這樣的足画。

通過(guò)id號(hào)取到某個(gè)老板雄驹,然后還有一個(gè)關(guān)聯(lián)的餐館號(hào)碼eatery_id.

老板肯定是某個(gè)餐館的老板,

老板boss_a當(dāng)然是eatery_id號(hào)碼這個(gè)餐館的老板淹辞。

更多的先不討論了医舆。

因?yàn)椋@里象缀,

有意思的地方已經(jīng)出來(lái)了蔬将。

table_eatery和table_boss全面的揭示了面向?qū)ο蟮谋举|(zhì):

擴(kuò)展和關(guān)聯(lián)

我們先建立起基礎(chǔ):eatery,然后呢央星?

當(dāng)我們需要新的東西的時(shí)候霞怀,擴(kuò)展eatery。

怎么擴(kuò)展呢等曼?

通過(guò)建立一個(gè)新的表格里烦。

那新的表格table_boss怎么跟table_eatery建立聯(lián)系呢?

通過(guò)在新擴(kuò)展出來(lái)的table_boss塞入eatery_id來(lái)指向table_eatery禁谦。

乍一看胁黑,是不是就是繼承呢?

先弄出個(gè)table_eatery對(duì)象州泊,然后繼承這個(gè)對(duì)象丧蘸,在上邊再弄上個(gè)boss_name。

不過(guò),仔細(xì)觀察 力喷,當(dāng)然知道不是繼承刽漂。 (而且,都知道弟孟,多數(shù)時(shí)候繼承不是好的面向?qū)ο螅?/p>

這里是"組合"贝咙。

在新的對(duì)象里放入舊有對(duì)象的一個(gè)引用,然后拂募,成了庭猩。

objectA   --->    objectB   [放入objectA的一個(gè)引用]

以此類(lèi)推,我們加深下關(guān)系型數(shù)據(jù)庫(kù)表格的建立陈症。

建立一個(gè)雇員表格:

    id
    employee_name
    eatery_id

建立一個(gè)餐館菜單:

    id
    menu_item
    menu_price
    eatery_id

...

這其實(shí)就是面向?qū)ο蟮倪^(guò)程蔼水。

所以,對(duì)于程序來(lái)說(shuō)录肯,設(shè)計(jì)這個(gè)餐館趴腋,可以這樣面向?qū)ο?

Eatery (build_date, city)

    build_date             // 建立日期
    city                      // 所在城市
    get_build_date()     // 報(bào)告建立日期
    get_city                // 報(bào)告所在城市

Boss (eatery)

    name                    // 老板名字
    set_name              // 任職老板
    get_name              // 當(dāng)前老板的名字

Employee (eatery)

    names                   // 雇員們的名字
    add_name              // 增加一個(gè)雇員
    remove_name         // 開(kāi)除一個(gè)雇員
    get_name(i)           // 報(bào)告第幾號(hào)雇員的名字
    get_names()          // 報(bào)告所有的雇員名字列表

Food (name, price)

    name                    // 菜的名字
    price                    // 菜的價(jià)格      
    get_name()           // 報(bào)告菜的名字
    get_price()           // 報(bào)告菜的價(jià)格

Menu (eatery)

    foods                   // 菜列表
    add_food(food)      // 加入菜
    remove_food(food) // 刪除菜
    get_food_price(i)   // 報(bào)告第幾號(hào)菜的價(jià)格
    get_food_prices     // 報(bào)告所有菜的價(jià)格
    get_food_names    // 報(bào)告所有菜的名字
    get_food_name(i)  // 報(bào)告第幾號(hào)菜的名字

Cook (name, food_names)

    name                    // 廚師名字
    food_names           // 廚師擅長(zhǎng)做的菜名
    get_name()           // 報(bào)告廚師的名字
    get_food_names()  // 報(bào)告廚師擅長(zhǎng)做的菜名列表
    make(food_name)   // 廚師制作名為food_name的菜

Cooklist (eatery)

    cooks                  // 餐館entery雇傭的廚師名字列表
    add_cook(cook)     // 增加一個(gè)廚師
    get_cook_names()  // 報(bào)告所有的餐館廚師名字
    get_cook_name(i)   // 報(bào)告第幾號(hào)廚師的名字

OK. 餐館構(gòu)造完畢,現(xiàn)在论咏,開(kāi)始運(yùn)營(yíng):

var entery_pie = new Eatery('2014-5-1', 'Beijing');  // 2014年5月1日优炬,在北京建立餐館pie

entery_pie.get_build_date();  // => 2014-5-1

entery_pie.get_city();  // => Beijing


var boss = new Boss(eatery_pie);  // 為餐館pie指認(rèn)老板

boss.set_name('Tom');  // 老板是Tom

 

var employee = new Employee(eatery_pie);  // 為餐館pie雇傭員工

employee.add_name('Lili');  // 雇傭Lili

employee.add_name('Lina');  // 雇傭Lina

employee.add_name('Jerry');  // 雇傭Jerry

employee.get_names();  // => Lili,Lina,Jerry

employee.get_name(1);  // => Lina

 

var menu = new Menu(eatery_pie);  // 為餐館pie開(kāi)設(shè)菜單

menu.add_food(new Food('milk', '12.00¥'));  // 加入價(jià)格12.00¥的牛奶

menu.add_food(new Food('rice', '26.00¥'));  // 加入價(jià)格26.00¥的炒飯

menu.get_food_names();  // => 牛奶,炒飯

menu.get_food_prices();  // => 12.00¥,26.00¥

menu.get_food_name(1);  // => 炒飯

 

var cooklist = new Cooklist(eatery_pie);  // 為餐館pie增加廚師

cooklist.add_cook(new Cook('Daxiong', ['milk', 'rice', 'tomoto'])); // 增加一個(gè)會(huì)做牛奶、炒飯潘靖、西紅柿的廚師

cooklist.add_cook(new Cook('Xiaoxiao', ['milk', 'rice']));  // 增加一個(gè)會(huì)做牛奶穿剖、炒飯的廚師

cooklist.get_cook_name(1).make('milk');  // Xiaoxiao廚師來(lái)一份牛奶

cooklist.get_cook_name(0).make('tomoto');  // Daxiong廚師來(lái)一份西紅柿

這就是我現(xiàn)在思想中的面向?qū)ο螅赡芎?jiǎn)單的模型卦溢,更多的擴(kuò)展和關(guān)聯(lián)糊余。

在很長(zhǎng)時(shí)間之前,我收集到的信息告訴我单寂,盡可能的封裝贬芥,并且 a.get().method() 表現(xiàn)的不夠隱蔽。

如果有a.get().nethod()宣决,應(yīng)該盡可能換成a.method()來(lái)隱藏蘸劈。

然而,現(xiàn)在我卻感覺(jué)到這樣教條式的做法尊沸,在許多時(shí)候是多余和低效的威沫。

比起把許多小對(duì)象裝起來(lái),扔到一個(gè)大對(duì)象里封裝洼专,我現(xiàn)在更喜歡建立一大堆的小對(duì)象棒掠,然后分批指派責(zé)任。

從許多方面來(lái)看屁商,簡(jiǎn)化代碼行數(shù)的外觀模式都是反模塊化的烟很,只用一個(gè)對(duì)象來(lái)操縱一大堆函數(shù)。

事實(shí)上,底層要通過(guò)層層傳遞雾袱,才能夠到達(dá)真正實(shí)現(xiàn)功能的地方恤筛。

這既是低效的,在編寫(xiě)擴(kuò)展的時(shí)候而且很困難芹橡。

如果你寫(xiě)完一個(gè)夠大的對(duì)象毒坛,當(dāng)需要增加內(nèi)容的時(shí)候,就會(huì)對(duì)這個(gè)對(duì)象的關(guān)聯(lián)“鏈”一籌莫展林说。

而打散的小對(duì)象群粘驰,更貼近函數(shù)式的風(fēng)格,只需要指定源對(duì)象的引用述么,就可以擴(kuò)展ta,而且是采用組合而不是繼承愕掏。


而且度秘,在某些方面,你會(huì)發(fā)現(xiàn)這其實(shí)就是函數(shù)式.

一個(gè)數(shù)據(jù)結(jié)構(gòu)Eatery饵撑,以及一大堆圍繞數(shù)據(jù)結(jié)構(gòu)Eatery的函數(shù)群:

eatery

fn1(eatery, arg1, arg2, ...)

fn2(eatery, arg1, arg2, ...)

fn3(eatery, arg1, arg2, ...)

...

好處是剑梳,非常易于擴(kuò)展(增加功能,增加內(nèi)容滑潘,增加關(guān)聯(lián)垢乙,...)和修改.

壞處是? e, ... 语卤,相比較傳統(tǒng)的OO教學(xué)追逮,會(huì)有一大堆“小星星”散亂在宇宙世界里,變得不那么透明粹舵,但是依然可以設(shè)定一個(gè)邊界來(lái)限定這個(gè)外層钮孵。

但是,我覺(jué)得眼滤,好處是絕對(duì)的巴席,因?yàn)檫@樣更符合函數(shù)的特性:

    輸入一個(gè)值,show me the result

    fn1(eatery_pie, arg1, arg2) => 餐館pie的信息 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诅需,一起剝皮案震驚了整個(gè)濱河市漾唉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌堰塌,老刑警劉巖赵刑,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蔫仙,居然都是意外死亡料睛,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)恤煞,“玉大人屎勘,你說(shuō)我怎么就攤上這事【影牵” “怎么了概漱?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)喜喂。 經(jīng)常有香客問(wèn)我瓤摧,道長(zhǎng),這世上最難降的妖魔是什么玉吁? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任照弥,我火速辦了婚禮,結(jié)果婚禮上进副,老公的妹妹穿的比我還像新娘这揣。我一直安慰自己,他們只是感情好影斑,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布给赞。 她就那樣靜靜地躺著,像睡著了一般矫户。 火紅的嫁衣襯著肌膚如雪片迅。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,713評(píng)論 1 312
  • 那天皆辽,我揣著相機(jī)與錄音柑蛇,去河邊找鬼。 笑死膳汪,一個(gè)胖子當(dāng)著我的面吹牛唯蝶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播遗嗽,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼粘我,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了痹换?” 一聲冷哼從身側(cè)響起征字,我...
    開(kāi)封第一講書(shū)人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎娇豫,沒(méi)想到半個(gè)月后匙姜,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡冯痢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年氮昧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了框杜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡袖肥,死狀恐怖咪辱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情椎组,我是刑警寧澤油狂,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站寸癌,受9級(jí)特大地震影響专筷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蒸苇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一磷蛹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧溪烤,春花似錦弦聂、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)匪凉。三九已至枪眉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間再层,已是汗流浹背贸铜。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留聂受,地道東北人蒿秦。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蛋济,于是被迫代替她去往敵國(guó)和親棍鳖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容