偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

從面向?qū)ο蟮脑O(shè)計模式看軟件設(shè)計

開發(fā) 后端
設(shè)計模式的英文是Design Pattern,模式是Pattern的漢譯。所謂Pattern就是一種規(guī)則,或是一種模型,或是一種習(xí)慣。Pattern這個東西到處都是,并不只有技術(shù)圏子里才有。

前些天發(fā)了一篇《如此理解面向?qū)ο缶幊獭返奈恼拢缓笠鹆舜蠹业臒嶙h。然后我在微博上說了一句——“那23個經(jīng)典的設(shè)計模式和OO半毛錢關(guān)系沒有,只不過人家用OO來實現(xiàn)罷了……OO的設(shè)計模式思想和Unix的設(shè)計思想基本沒什么差別”,結(jié)果引來了一點點爭議。所以,我寫下這篇文章把我的觀點說明一下。我希望這樣可以讓大家更容易地理解什么是設(shè)計模式。我順便幫OO和 Unix/Linux搞搞基。

什么是模式

在正式說明GoF的那23個經(jīng)典的設(shè)計模式其實和OO關(guān)系不大并和Unix的設(shè)計思想很相似的這個觀點之前,讓我先來說說什么是模式?設(shè)計模式的英文是Design Pattern,模式是Pattern的漢譯。所謂Pattern就是一種規(guī)則,或是一種模型,或是一種習(xí)慣。Pattern這個東西到處都是,并不只有技術(shù)圏子里才有。比如:

  • 文章有文章的Pattern。如新聞有新聞的Pattern(第一段話簡述了整個新聞),詩歌總是抒情的,論文總是死板的,講稿總是高談的,漫畫總是幽默的,……
  • 小說有小說的Pattern。比如,
  1. 武俠小說必然要整個武林大會,整幾個NB的武功和大師,分個正派和反派,還有一個或數(shù)個驚天陰謀,壞人總是要在一開始占盡優(yōu)勢,好人總是要力挽狂瀾……
  2. 言情小說總是要有第三者,總是要有負心人,里面的女子總是要哭得死去活來,但又癡心不改,……
  •  春節(jié)的模式是,回家,吃餃子,放個鞭炮,給壓歲錢,同學(xué)聚會…… 同學(xué)聚會的模式基本上都是在飯桌上回憶一下校園時光,比較一下各自的當(dāng)前處境…… ……

這就是Pattern,只要你細心觀察,你會發(fā)現(xiàn)這世間有很多很多的Pattern。

GoF的23個設(shè)計模式

《設(shè)計模式》這本書中,GoF這四個人總結(jié)了23個經(jīng)典的面向?qū)ο蟮脑O(shè)計模式,某中有5個創(chuàng)建模式,7個結(jié)構(gòu)模式,11個行為模式。很多人都會覺得這是面向?qū)ο蟮脑O(shè)計模式,很多人也覺得非面向?qū)ο蟛荒苡眠@些模式。我覺得這是一種教條主義。就像《那些流行的編程方法》中的“設(shè)計模式驅(qū)動型編程”一樣,就像《如此理解面向?qū)ο蟆芬粯拥哪敲吹幕?/p>

好了,回到我的論點——“GoF的這23個設(shè)計模式和OO關(guān)系不大,并且和Unix的設(shè)計思想基本一致,只不過GoF用OO實現(xiàn)了它們”,就像我上面說過的那些生活中的Pattern一樣,只要你仔細思考,你會發(fā)現(xiàn)這23個設(shè)計模式在我們的生活和社會中也能有他們的身影。而且也一樣可以用OO的方式實現(xiàn)之。

讓我們來看看這23個經(jīng)典的設(shè)計模式中的幾個常用的模式:

Factory 模式,這個模式可能是是個人都知道的模式。這個模式在現(xiàn)實社會中就像各種工廠一樣,工廠跨界的不多,基本上都是在生產(chǎn)同一類的產(chǎn)品,有的生產(chǎn)汽車,有的生產(chǎn)電視,有的生產(chǎn)衣服,有的生產(chǎn)衛(wèi)生紙……基本上來說,一個生產(chǎn)線上只有做同一類的東西。這和 Factory模式很相似。編程中,像內(nèi)存池,線程池,連接池等池化技術(shù)都是這個模式,當(dāng)然,F(xiàn)actory給你的一個對象,而不單單只是資源,factory創(chuàng)建出來的對象都有同樣的接口可以被多態(tài)調(diào)用。這其實和Unix把所有的硬件都factory成文件一樣,并提供了read/write等文件操作來讓你操作任意設(shè)備的I/O。

Abstract Factory:抽象工廠這個模式是創(chuàng)建一組有同一主題的不同的類。這個模式在現(xiàn)實社會當(dāng)中也有很多例子,比如:

  • 移動公司的合約機計劃,88套餐(通話100分鐘,短信100條,彩信,20條,上網(wǎng)200M),128套餐(通話200分鐘,短信150條,彩信50條,上網(wǎng)500M)……
  • 家里的裝修,總是要有廚衛(wèi),有門,有燈,有沙發(fā),有茶幾,有床,有衣柜,有電視,有冰箱,有洗衣機……,這些都是必需的,只是每個家庭里的具體裝修不一樣。
  • Diablo游戲中的Normal,Hard,Nightmare,Hell模式,這些模式的怪和場景和故事情況都差不多,就是每個場景的怪物和裝備的屬性不一樣?;蚴荳arCraft中的地圖就是一個Abstract Factory模式(注:Warcraft的地圖什么都能干)。這和學(xué)校中的小學(xué),初中,高中,大學(xué)差不多,都是一樣的學(xué)習(xí)環(huán)境,一樣的教學(xué)方式,一樣的教室,都要期中考和期末考,都有班長和科代表,就是學(xué)的東西的難度不一樣,但基本上都是語文,英語,數(shù),理,化,還有永遠都有的政治課。學(xué)校就是一個抽象工廠。

這就是抽象工廠的業(yè)務(wù)模型(或是:Business Pattern),你覺得是不是不一定非要用OO來實現(xiàn)這樣的模式?(我們思考一下,我們會不會被先入為主了,覺得不會OO都不知道怎么實現(xiàn)了),不用OO,用相同格式但內(nèi)容不同的配置文件是不是也能實現(xiàn)?在Unix下,抽象工廠這個模式在Unix下就像是/etc/rcX.d下的那些東西,1代表命令行單用戶,2,代表命令行多用戶,3代表命令行多用戶完整模式啟動,5代表圖形界面啟動,0代表關(guān)機,6代表重啟,你要切換的話,init <X>就行了

Prototype模式,原型模式,復(fù)制一個類的實現(xiàn)。這個模式在現(xiàn)實中的例子也有很多:傳真,復(fù)印,都是這個模式。Unix進程和Github項目的Fork就是一種。進程fork明顯不是OO的模型(參看:關(guān)于Fork的一道面試題)。用非OO的方法同樣可以實現(xiàn)這個模式。

Singleton模式,單例模式。生活中,公司只有一個CEO,法律限制你只能有一個老婆,你只能有一個身份證號,一個TCP端口只能被一個進程使用,等等。軟件開發(fā)方面,并不一定只有OO才能做到,你可以用一個全局變量,一個中心服務(wù)器,甚至可以使用行政手段來約束開發(fā)中不會出現(xiàn)多個實例。Unix下實現(xiàn)單例進程的一個最常用的實踐是在進程啟動的時候用“(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)”模式打開一個“鎖文件”。

Adapter模式,適配器模式。可以兼容歐洲美國中國的插頭或插座,萬能讀卡器,可以播放各種格式多媒體文件的插放器,可以解析FTP/HTTP/HTTPS/等網(wǎng)絡(luò)協(xié)議的瀏覽器,可以兼容各大銀行的銀聯(lián)接口、支付寶、Paypal、VISA等銀行接口,可以適配各種后端的解釋器的Nginx或Apache,等等。用非OO的編程方式就是重新包裝成一個標準接口。這個模式很像Unix下的/dev下的那些文件,操作系統(tǒng)把系統(tǒng)設(shè)備適配成文件,于是你就可以使用read/write來進行讀寫了。

Bridge模式,橋接模式。這個模式用的更多,比如一個燈具可以接各種燈泡或燈管,一個電鉆可以換上不同的鉆頭來適應(yīng)不同的材料,一輛汽車可以隨時更換不同的輪胎來適應(yīng)不同的路面,你的桌面可以隨時更換一個圖片來適應(yīng)你的心情,你的單反相機可以更換不同的鏡頭來拍不同的照片…… 橋接模式說白了就是組件化,模塊化,可以自由拼裝。在OO中,其主要是通過讓業(yè)務(wù)類組合一個標準接口來完成,這在非OO的程序設(shè)計中用得實在是太多了,主要是通過回調(diào)函數(shù)或是標準接口來實現(xiàn)。這個也是Unix設(shè)計哲學(xué)中的主要思想。在Unix中,文件的權(quán)限使用的就是Bridge模式,標準接口是用戶,用戶組和其它,rwx三個模式,然后用 chmod/chown改一改,這文件就有不同的屬主和屬性了。

Decorator模式,裝飾模式。這個模式在生活中太多了,你給你的手機或電腦貼個什么,掛個什么,吃東西的時候加點什么佐料,多點肉還是多個蛋,一個Unix/Linux命令的各種參數(shù)是對這個命令的修飾,等等。我覺得這個模式在Unix中最經(jīng)常的體現(xiàn)就是通過管道把命令連接起來來完成一個功能,比如:ps -elf  是列進程的,用管道 grep hchen就可以達到過濾的目的,grep的邏輯沒有侵入ps中,grep 修飾了 ps,但是其組合起來完成了一個特定的功能??梢?,這和OO沒有什么關(guān)系。

Facade模式,這個模式我們每個人從會編程的時候就在無意識地用這個模式了。這個模式就是把一大堆類拼裝起來,并統(tǒng)一往外提供提口。在現(xiàn)實生活中這樣的例子太多了,比如:旅行社把機票,酒店,景點,導(dǎo)游,司機,進店打了一個包叫旅行;IBM把主機,存儲,OS,J2EE,DB,網(wǎng)絡(luò),流程打了個包叫企業(yè)級解決方案。Unix中最典型的一個例子就是用Shell腳本組合各種命令來創(chuàng)造一個新的功能,這是的Shell中的各種命令通過標準I/O這個接口進行組合交互。

Proxy模式,代理模式。我們租個房,買個機票,打個官司,都少不了代理,人大代表代理了老百姓去行使政治權(quán)力。我們?nèi)ワ堭^里吃飯也是一種代理模式,因為我們只管吃就好了,洗菜做飯洗碗的工作都被Proxy幫你干了,于是你就省事多了。操作系統(tǒng)就是硬件的代理,CDN就是網(wǎng)站的代理,……使用代理你可以讓事情變理更簡單,也可以在代理層加入一些權(quán)限檢查,這樣可以讓業(yè)務(wù)模塊更關(guān)注業(yè)務(wù),而把一些非業(yè)務(wù)的事情剝離出來交給代理以完成解耦??梢娺@個模式和OO沒啥關(guān)系。Unix下這個模式最佳體現(xiàn)就是Shell,它代理了系統(tǒng)調(diào)用并提供UI。還有很多命令會幫你把/proc目錄下的那些文件內(nèi)容整理和顯示出來。

Chain of Responsibility模式,劫匪來搶銀行,保安搞不定,就交給110,110搞不定就交給武警。有什么事件發(fā)生時的響應(yīng)的Escalation Path,辦公中的逐級審批。這個模式用一個函數(shù)指針數(shù)組或是棧結(jié)構(gòu)就可以實現(xiàn)了。這個思想很像編程中的異常處理機制,一層一層地往上傳遞異常直到異常被捕捉。在Unix下,一個最簡單的例子就是用 && 或 || 來把命令拼起來,如:cmd1 && cmd2  或 cmd3 || cmd4 , 如果cmd1失敗了,cmd2就不會執(zhí)行,如果cmd3失敗了,cmd4才會執(zhí)行。如: cd lib && rm -rf .o 或 ping -c1 coolshell.cn && ssh haoel@coolshell.cn

Command模式,這恐怕是軟件里最多的模式了,比如:編譯器里的Undo/Redo,宏錄制。還有數(shù)據(jù)庫的事務(wù)處理,線程池,設(shè)置向?qū)?,包括程序并行?zhí)行的指令集等等。這個模式主要是把一個對象的行為封裝成一個一個的有相同接口的command,然后交給一個統(tǒng)一的命令執(zhí)行器執(zhí)行或管理這些命令。這個模式和我們的Unix/Linux機器啟動時在/etc/init.d下的那些S和K開頭的腳本很像,把各種daemon的啟動和退出行為封裝成一個腳本其支持reload/start/stop/status這樣的命令,然后把他們按一定的規(guī)范做符號鏈接到/etc/init.d目錄下,這樣操作系統(tǒng)就會接管這些daemon的啟動和退出

Observer模式,觀察者模式,這個模式也叫pub-sub模式,很像我們用手機訂閱手機報,微博的 follow的信息流也是這樣的一個模式。MVC中的C會sub V中的事件,用非OO的方式其實也是一個回調(diào)函數(shù)的事。在很多異步系統(tǒng)中,你需要知道最終的調(diào)用有沒有成功,比如說調(diào)用支付寶的支付接口,你需要向支付寶注冊一個回調(diào)的接口,以便支付寶回調(diào)你。Linux下的一些系統(tǒng)調(diào)用如epoll/aio/inotify/signal都是這種思路

Strategy 模式,策略模式,這個模式和Bridge模式很像,只不過Bridge是結(jié)構(gòu)模式,其主要是用于對象的構(gòu)造;而Strategy是行為模式,主要是用于對象的行為。策略模式很像瀏覽器里的各種插件,只要你裝了某個插件,你就有某個功能。你可以安裝多個插件來讓你的瀏覽器有更多的功能(書本上的這個模式是你只能選用一個算法,當(dāng)然,我們不用那么教條)。就像《你可能不知道的Shell》中的那個設(shè)置設(shè)置$EDITOR變量后可以按ctrl+x e啟動編譯器,或是用set -o vi或set -o emacs 來讓自己的shell像vi或 emacs 一樣,或是像find -exec或xargs一樣的拼裝命令。

Bridge 和 Strategy是OO設(shè)計模式里的“Favor Composition Over Inheritance” 的典范,其實現(xiàn)了接口與實現(xiàn)分離的。 Unix中的Shell就是一種,你可隨意地更換不同的Shell。還有Emacs中的LISP驅(qū)動C,C實現(xiàn)了引擎,交給LISP實現(xiàn)邏輯。把程序分為前端和后端,通過socket專用應(yīng)用協(xié)議進行通訊,前端實現(xiàn)策略,后端實現(xiàn)機制。再看看makefile把編譯器和源代碼的解耦,命令行輸出這個接口可以把一個復(fù)雜的功能解耦并抽像成各種各樣小而美的小功能命令,等等這樣的例子,你會發(fā)現(xiàn),還有大量的編程框架都會多少采用這樣的思想,可以讓你的軟件像更換汽車零件一樣方便。我在用Unix的設(shè)計思想來應(yīng)對變更的需求中說過燈具廠,燈泡廠,和開關(guān)廠的例子。

后記

因為寫作倉促,上面的那些東西,可能會你讓你覺得有些牽強,那么抱歉了,你可以幫我看看在生活中和 Unix里有沒有更帥的例子。

不過,我們會發(fā)現(xiàn)上面OO搞出來的那么多模式在Unix下看來好像沒有那么復(fù)雜,而且Unix下看起來并沒有那么多模式,而且Unix中的設(shè)計模式無非就是這么幾個關(guān)鍵詞:單一,簡潔,模塊,拼裝。我們再來看看OO設(shè)計的兩大準則:1)鐘情于組合而不是繼承,2)依賴于接口而不是實現(xiàn)。還有S.O.L.I.D原則也一樣(如果你仔細觀察,你會發(fā)現(xiàn)SOLID原則在Unix下也是完美地體現(xiàn))。你看,Unix和OO設(shè)計模式是不是完美的統(tǒng)一嗎?

我有種強烈的感覺——Unix對這些所謂的OO的設(shè)計模式實現(xiàn)得更好。因為Unix就一條設(shè)計模式!再次推薦《The Art of Unix Programming》

[[74502]]

餐后甜點

我上面提到了《The Art of Unix Programming》,所以我有必要再談?wù)勥@本書中我中毒最深的一章《模塊性:保持清晰和簡潔》中所談到的膠合層。

膠合層這一節(jié)中說了,我們開發(fā)軟件一般要么Top-Down,要么Bottom-Up,這兩種方法都有好有不好。頂層一般是應(yīng)用邏輯層,底層一般是原語層(我理解為技術(shù)沉淀層,或是技術(shù)基礎(chǔ)層)。自頂向下的開發(fā),你可能會因為開發(fā)到底層后發(fā)現(xiàn)底層可沉淀的東西越來越不爽(因為被可能被很多業(yè)務(wù)邏輯所侵入),如果自底向上的開發(fā),你可能越到上層你越發(fā)現(xiàn)很多你下面干的基礎(chǔ)上工作有很多用不上(比如干多了)。所以,最好的方式是同時進行,一會頂層,一會底層,來來回回的開發(fā)——說白了就是在開發(fā)中不斷的重構(gòu),邊開發(fā)邊理解邊沉淀。

無論怎么樣,你會發(fā)現(xiàn)需要一層膠合層來膠合業(yè)務(wù)邏輯層和底層原語層(軟件開發(fā)中的業(yè)務(wù)層和技術(shù)層的膠合),Unix的設(shè)計哲學(xué)認為,這層膠合層應(yīng)該盡量地薄,膠合層越多,我們就只能在其中苦苦掙扎。

其實,膠合層原則就是分離原則上更為上層地體現(xiàn),策略(業(yè)務(wù)邏輯)和機制(基礎(chǔ)技術(shù)或原語)的清楚的分離。你可以看到,OO和 Unix都是在做這樣的分離。但是需要注意到的時,OO用抽象接口來做這個分離——很多OO的模式中,抽象層太多了,導(dǎo)致膠合層太過于復(fù)雜了,也就是說,OO鼓勵了——“厚重地膠合和復(fù)雜層次”,反而增加了程序的復(fù)雜度(這種情況在惡化中)。而Unix采用的是薄的膠合層,薄地相當(dāng)?shù)膬?yōu)雅。(通過這段話的描述,我相信你會明白了《如此理解面向?qū)ο缶幊獭分械膫€例子——為什么用OO來實現(xiàn)會比用非OO來實現(xiàn)更為地惡心——那就是因為OO膠合層太復(fù)雜了)

OO的最大的問題就——接口復(fù)雜度太高,膠合層太多!(注:Unix編程藝術(shù)這本書里說了軟件有三個復(fù)雜度:代碼量、接口、實現(xiàn),這三個東西構(gòu)成了我們的軟件復(fù)雜度)

再送一個果盤

大家一定記得《SteveY對Amazon和Google平臺的長篇大論》中Amazon中那個令人非常向往的SOA式的架構(gòu)。因為以前在Amazon,有些話不好說。現(xiàn)在可以說了,我在Amazon里,我個人對這個服務(wù)化的架構(gòu)相當(dāng)?shù)牟淮?,太?fù)雜,復(fù)雜以亂七八糟,方向是好的,想法也是好的,但是這東西和OO一樣,造成大量的接口復(fù)雜度,今天的Amazon,完全沒人知道各個服務(wù)是怎么個調(diào)用的,一團亂麻(其內(nèi)部并不像你看到的AWS那么的美妙。注:AWS是非常不錯的,是相當(dāng)好的設(shè)計)。

那么我們怎么來解決SOA的接口復(fù)雜度問題?其實,Unix早就給出了答案——數(shù)據(jù)驅(qū)動編程(詳見:《Unix 編程藝術(shù)》的第9.1章),在我離開Amazon的時候,美國總部的Principle SDE們在吐槽今天Amazon的SOA架構(gòu),更好的架構(gòu)應(yīng)該是數(shù)據(jù)驅(qū)動式的。(今天還在Amazon的同學(xué)可以上內(nèi)網(wǎng)boardcast上看看相關(guān)的 Principle Talk視頻)

(瞎扯一句:這本來是我想在2012年杭州QCon上的分享的一個主題,無奈當(dāng)時被大會組織者給拒了,所以只好講了一個《建一支小團隊》,今天有多人還是不能明白甚至反感我的那個《小團隊》的演講,但是我相信那是必然的趨勢,就像十年前大家在說“程序員只能干到30歲”時,當(dāng)時的我我卻毫不猶豫地相信十年后,30歲以上的有經(jīng)驗的老程序員一定會成為各個公司角逐和竟爭的紅人)

原文鏈接:http://coolshell.cn/articles/8961.html

責(zé)任編輯:陳四芳 來源: 酷殼網(wǎng)
相關(guān)推薦

2021-11-23 20:41:05

對象軟件設(shè)計

2019-08-12 14:45:50

軟件設(shè)計Java

2010-06-13 10:33:54

面向?qū)ο骍ML技術(shù)

2010-08-11 09:15:07

設(shè)計模式Python

2021-03-10 08:20:54

設(shè)計模式OkHttp

2019-01-31 10:48:28

軟件開發(fā)者 設(shè)計

2011-01-19 10:50:31

軟件設(shè)計師

2010-06-11 14:01:47

面向?qū)ο骍ML技術(shù)

2023-10-19 13:43:00

設(shè)計模式軟件設(shè)計

2011-07-14 14:46:46

設(shè)計模式

2022-09-19 06:25:14

設(shè)計模式GoF

2017-08-28 15:00:20

軟件系統(tǒng)架構(gòu)風(fēng)格

2011-07-21 14:33:02

設(shè)計模式

2013-04-17 10:46:54

面向?qū)ο?/a>

2013-05-08 09:12:44

2019-04-28 16:10:50

設(shè)計Redux前端

2010-06-12 15:52:18

面向?qū)ο骍ML技術(shù)

2012-06-07 10:11:01

面向?qū)ο?/a>設(shè)計原則Java

2010-08-02 16:19:00

ibmdw面向?qū)ο?/a>

2022-01-13 10:19:34

軟件汽車 技術(shù)
點贊
收藏

51CTO技術(shù)棧公眾號