從面向?qū)ο蟮脑O(shè)計(jì)模式看軟件設(shè)計(jì)
前些天發(fā)了一篇《如此理解面向?qū)ο缶幊獭返奈恼?,然后引起了大家的熱議。然后我在微博上說(shuō)了一句——“那23個(gè)經(jīng)典的設(shè)計(jì)模式和OO半毛錢關(guān)系沒(méi)有,只不過(guò)人家用OO來(lái)實(shí)現(xiàn)罷了……OO的設(shè)計(jì)模式思想和Unix的設(shè)計(jì)思想基本沒(méi)什么差別”,結(jié)果引來(lái)了一點(diǎn)點(diǎn)爭(zhēng)議。所以,我寫下這篇文章把我的觀點(diǎn)說(shuō)明一下。我希望這樣可以讓大家更容易地理解什么是設(shè)計(jì)模式。我順便幫OO和 Unix/Linux搞搞基。
什么是模式
在正式說(shuō)明GoF的那23個(gè)經(jīng)典的設(shè)計(jì)模式其實(shí)和OO關(guān)系不大并和Unix的設(shè)計(jì)思想很相似的這個(gè)觀點(diǎn)之前,讓我先來(lái)說(shuō)說(shuō)什么是模式?設(shè)計(jì)模式的英文是Design Pattern,模式是Pattern的漢譯。所謂Pattern就是一種規(guī)則,或是一種模型,或是一種習(xí)慣。Pattern這個(gè)東西到處都是,并不只有技術(shù)圏子里才有。比如:
- 文章有文章的Pattern。如新聞?dòng)行侣劦腜attern(第一段話簡(jiǎn)述了整個(gè)新聞),詩(shī)歌總是抒情的,論文總是死板的,講稿總是高談的,漫畫總是幽默的,……
- 小說(shuō)有小說(shuō)的Pattern。比如,
- 武俠小說(shuō)必然要整個(gè)武林大會(huì),整幾個(gè)NB的武功和大師,分個(gè)正派和反派,還有一個(gè)或數(shù)個(gè)驚天陰謀,壞人總是要在一開始占盡優(yōu)勢(shì),好人總是要力挽狂瀾……
- 言情小說(shuō)總是要有第三者,總是要有負(fù)心人,里面的女子總是要哭得死去活來(lái),但又癡心不改,……
- 春節(jié)的模式是,回家,吃餃子,放個(gè)鞭炮,給壓歲錢,同學(xué)聚會(huì)…… 同學(xué)聚會(huì)的模式基本上都是在飯桌上回憶一下校園時(shí)光,比較一下各自的當(dāng)前處境…… ……
這就是Pattern,只要你細(xì)心觀察,你會(huì)發(fā)現(xiàn)這世間有很多很多的Pattern。
GoF的23個(gè)設(shè)計(jì)模式
《設(shè)計(jì)模式》這本書中,GoF這四個(gè)人總結(jié)了23個(gè)經(jīng)典的面向?qū)ο蟮脑O(shè)計(jì)模式,某中有5個(gè)創(chuàng)建模式,7個(gè)結(jié)構(gòu)模式,11個(gè)行為模式。很多人都會(huì)覺(jué)得這是面向?qū)ο蟮脑O(shè)計(jì)模式,很多人也覺(jué)得非面向?qū)ο蟛荒苡眠@些模式。我覺(jué)得這是一種教條主義。就像《那些流行的編程方法》中的“設(shè)計(jì)模式驅(qū)動(dòng)型編程”一樣,就像《如此理解面向?qū)ο蟆芬粯拥哪敲吹幕?/p>
好了,回到我的論點(diǎn)——“GoF的這23個(gè)設(shè)計(jì)模式和OO關(guān)系不大,并且和Unix的設(shè)計(jì)思想基本一致,只不過(guò)GoF用OO實(shí)現(xiàn)了它們”,就像我上面說(shuō)過(guò)的那些生活中的Pattern一樣,只要你仔細(xì)思考,你會(huì)發(fā)現(xiàn)這23個(gè)設(shè)計(jì)模式在我們的生活和社會(huì)中也能有他們的身影。而且也一樣可以用OO的方式實(shí)現(xiàn)之。
讓我們來(lái)看看這23個(gè)經(jīng)典的設(shè)計(jì)模式中的幾個(gè)常用的模式:
Factory 模式,這個(gè)模式可能是是個(gè)人都知道的模式。這個(gè)模式在現(xiàn)實(shí)社會(huì)中就像各種工廠一樣,工廠跨界的不多,基本上都是在生產(chǎn)同一類的產(chǎn)品,有的生產(chǎn)汽車,有的生產(chǎn)電視,有的生產(chǎn)衣服,有的生產(chǎn)衛(wèi)生紙……基本上來(lái)說(shuō),一個(gè)生產(chǎn)線上只有做同一類的東西。這和 Factory模式很相似。編程中,像內(nèi)存池,線程池,連接池等池化技術(shù)都是這個(gè)模式,當(dāng)然,F(xiàn)actory給你的一個(gè)對(duì)象,而不單單只是資源,factory創(chuàng)建出來(lái)的對(duì)象都有同樣的接口可以被多態(tài)調(diào)用。這其實(shí)和Unix把所有的硬件都factory成文件一樣,并提供了read/write等文件操作來(lái)讓你操作任意設(shè)備的I/O。
Abstract Factory:抽象工廠這個(gè)模式是創(chuàng)建一組有同一主題的不同的類。這個(gè)模式在現(xiàn)實(shí)社會(huì)當(dāng)中也有很多例子,比如:
- 移動(dòng)公司的合約機(jī)計(jì)劃,88套餐(通話100分鐘,短信100條,彩信,20條,上網(wǎng)200M),128套餐(通話200分鐘,短信150條,彩信50條,上網(wǎng)500M)……
- 家里的裝修,總是要有廚衛(wèi),有門,有燈,有沙發(fā),有茶幾,有床,有衣柜,有電視,有冰箱,有洗衣機(jī)……,這些都是必需的,只是每個(gè)家庭里的具體裝修不一樣。
- Diablo游戲中的Normal,Hard,Nightmare,Hell模式,這些模式的怪和場(chǎng)景和故事情況都差不多,就是每個(gè)場(chǎng)景的怪物和裝備的屬性不一樣。或是WarCraft中的地圖就是一個(gè)Abstract Factory模式(注:Warcraft的地圖什么都能干)。這和學(xué)校中的小學(xué),初中,高中,大學(xué)差不多,都是一樣的學(xué)習(xí)環(huán)境,一樣的教學(xué)方式,一樣的教室,都要期中考和期末考,都有班長(zhǎng)和科代表,就是學(xué)的東西的難度不一樣,但基本上都是語(yǔ)文,英語(yǔ),數(shù),理,化,還有永遠(yuǎn)都有的政治課。學(xué)校就是一個(gè)抽象工廠。
這就是抽象工廠的業(yè)務(wù)模型(或是:Business Pattern),你覺(jué)得是不是不一定非要用OO來(lái)實(shí)現(xiàn)這樣的模式?(我們思考一下,我們會(huì)不會(huì)被先入為主了,覺(jué)得不會(huì)OO都不知道怎么實(shí)現(xiàn)了),不用OO,用相同格式但內(nèi)容不同的配置文件是不是也能實(shí)現(xiàn)?在Unix下,抽象工廠這個(gè)模式在Unix下就像是/etc/rcX.d下的那些東西,1代表命令行單用戶,2,代表命令行多用戶,3代表命令行多用戶完整模式啟動(dòng),5代表圖形界面啟動(dòng),0代表關(guān)機(jī),6代表重啟,你要切換的話,init <X>就行了。
Prototype模式,原型模式,復(fù)制一個(gè)類的實(shí)現(xiàn)。這個(gè)模式在現(xiàn)實(shí)中的例子也有很多:傳真,復(fù)印,都是這個(gè)模式。Unix進(jìn)程和Github項(xiàng)目的Fork就是一種。進(jìn)程fork明顯不是OO的模型(參看:關(guān)于Fork的一道面試題)。用非OO的方法同樣可以實(shí)現(xiàn)這個(gè)模式。
Singleton模式,單例模式。生活中,公司只有一個(gè)CEO,法律限制你只能有一個(gè)老婆,你只能有一個(gè)身份證號(hào),一個(gè)TCP端口只能被一個(gè)進(jìn)程使用,等等。軟件開發(fā)方面,并不一定只有OO才能做到,你可以用一個(gè)全局變量,一個(gè)中心服務(wù)器,甚至可以使用行政手段來(lái)約束開發(fā)中不會(huì)出現(xiàn)多個(gè)實(shí)例。Unix下實(shí)現(xiàn)單例進(jìn)程的一個(gè)最常用的實(shí)踐是在進(jìn)程啟動(dòng)的時(shí)候用“(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)”模式打開一個(gè)“鎖文件”。
Adapter模式,適配器模式??梢约嫒輾W洲美國(guó)中國(guó)的插頭或插座,萬(wàn)能讀卡器,可以播放各種格式多媒體文件的插放器,可以解析FTP/HTTP/HTTPS/等網(wǎng)絡(luò)協(xié)議的瀏覽器,可以兼容各大銀行的銀聯(lián)接口、支付寶、Paypal、VISA等銀行接口,可以適配各種后端的解釋器的Nginx或Apache,等等。用非OO的編程方式就是重新包裝成一個(gè)標(biāo)準(zhǔn)接口。這個(gè)模式很像Unix下的/dev下的那些文件,操作系統(tǒng)把系統(tǒng)設(shè)備適配成文件,于是你就可以使用read/write來(lái)進(jìn)行讀寫了。
Bridge模式,橋接模式。這個(gè)模式用的更多,比如一個(gè)燈具可以接各種燈泡或燈管,一個(gè)電鉆可以換上不同的鉆頭來(lái)適應(yīng)不同的材料,一輛汽車可以隨時(shí)更換不同的輪胎來(lái)適應(yīng)不同的路面,你的桌面可以隨時(shí)更換一個(gè)圖片來(lái)適應(yīng)你的心情,你的單反相機(jī)可以更換不同的鏡頭來(lái)拍不同的照片…… 橋接模式說(shuō)白了就是組件化,模塊化,可以自由拼裝。在OO中,其主要是通過(guò)讓業(yè)務(wù)類組合一個(gè)標(biāo)準(zhǔn)接口來(lái)完成,這在非OO的程序設(shè)計(jì)中用得實(shí)在是太多了,主要是通過(guò)回調(diào)函數(shù)或是標(biāo)準(zhǔn)接口來(lái)實(shí)現(xiàn)。這個(gè)也是Unix設(shè)計(jì)哲學(xué)中的主要思想。在Unix中,文件的權(quán)限使用的就是Bridge模式,標(biāo)準(zhǔn)接口是用戶,用戶組和其它,rwx三個(gè)模式,然后用 chmod/chown改一改,這文件就有不同的屬主和屬性了。
Decorator模式,裝飾模式。這個(gè)模式在生活中太多了,你給你的手機(jī)或電腦貼個(gè)什么,掛個(gè)什么,吃東西的時(shí)候加點(diǎn)什么佐料,多點(diǎn)肉還是多個(gè)蛋,一個(gè)Unix/Linux命令的各種參數(shù)是對(duì)這個(gè)命令的修飾,等等。我覺(jué)得這個(gè)模式在Unix中最經(jīng)常的體現(xiàn)就是通過(guò)管道把命令連接起來(lái)來(lái)完成一個(gè)功能,比如:ps -elf 是列進(jìn)程的,用管道 grep hchen就可以達(dá)到過(guò)濾的目的,grep的邏輯沒(méi)有侵入ps中,grep 修飾了 ps,但是其組合起來(lái)完成了一個(gè)特定的功能。可見,這和OO沒(méi)有什么關(guān)系。
Facade模式,這個(gè)模式我們每個(gè)人從會(huì)編程的時(shí)候就在無(wú)意識(shí)地用這個(gè)模式了。這個(gè)模式就是把一大堆類拼裝起來(lái),并統(tǒng)一往外提供提口。在現(xiàn)實(shí)生活中這樣的例子太多了,比如:旅行社把機(jī)票,酒店,景點(diǎn),導(dǎo)游,司機(jī),進(jìn)店打了一個(gè)包叫旅行;IBM把主機(jī),存儲(chǔ),OS,J2EE,DB,網(wǎng)絡(luò),流程打了個(gè)包叫企業(yè)級(jí)解決方案。Unix中最典型的一個(gè)例子就是用Shell腳本組合各種命令來(lái)創(chuàng)造一個(gè)新的功能,這是的Shell中的各種命令通過(guò)標(biāo)準(zhǔn)I/O這個(gè)接口進(jìn)行組合交互。
Proxy模式,代理模式。我們租個(gè)房,買個(gè)機(jī)票,打個(gè)官司,都少不了代理,人大代表代理了老百姓去行使政治權(quán)力。我們?nèi)ワ堭^里吃飯也是一種代理模式,因?yàn)槲覀冎还艹跃秃昧?,洗菜做飯洗碗的工作都被Proxy幫你干了,于是你就省事多了。操作系統(tǒng)就是硬件的代理,CDN就是網(wǎng)站的代理,……使用代理你可以讓事情變理更簡(jiǎn)單,也可以在代理層加入一些權(quán)限檢查,這樣可以讓業(yè)務(wù)模塊更關(guān)注業(yè)務(wù),而把一些非業(yè)務(wù)的事情剝離出來(lái)交給代理以完成解耦??梢娺@個(gè)模式和OO沒(méi)啥關(guān)系。Unix下這個(gè)模式最佳體現(xiàn)就是Shell,它代理了系統(tǒng)調(diào)用并提供UI。還有很多命令會(huì)幫你把/proc目錄下的那些文件內(nèi)容整理和顯示出來(lái)。
Chain of Responsibility模式,劫匪來(lái)?yè)屻y行,保安搞不定,就交給110,110搞不定就交給武警。有什么事件發(fā)生時(shí)的響應(yīng)的Escalation Path,辦公中的逐級(jí)審批。這個(gè)模式用一個(gè)函數(shù)指針數(shù)組或是棧結(jié)構(gòu)就可以實(shí)現(xiàn)了。這個(gè)思想很像編程中的異常處理機(jī)制,一層一層地往上傳遞異常直到異常被捕捉。在Unix下,一個(gè)最簡(jiǎn)單的例子就是用 && 或 || 來(lái)把命令拼起來(lái),如:cmd1 && cmd2 或 cmd3 || cmd4 , 如果cmd1失敗了,cmd2就不會(huì)執(zhí)行,如果cmd3失敗了,cmd4才會(huì)執(zhí)行。如: cd lib && rm -rf .o 或 ping -c1 coolshell.cn && ssh haoel@coolshell.cn
Command模式,這恐怕是軟件里最多的模式了,比如:編譯器里的Undo/Redo,宏錄制。還有數(shù)據(jù)庫(kù)的事務(wù)處理,線程池,設(shè)置向?qū)?,包括程序并行?zhí)行的指令集等等。這個(gè)模式主要是把一個(gè)對(duì)象的行為封裝成一個(gè)一個(gè)的有相同接口的command,然后交給一個(gè)統(tǒng)一的命令執(zhí)行器執(zhí)行或管理這些命令。這個(gè)模式和我們的Unix/Linux機(jī)器啟動(dòng)時(shí)在/etc/init.d下的那些S和K開頭的腳本很像,把各種daemon的啟動(dòng)和退出行為封裝成一個(gè)腳本其支持reload/start/stop/status這樣的命令,然后把他們按一定的規(guī)范做符號(hào)鏈接到/etc/init.d目錄下,這樣操作系統(tǒng)就會(huì)接管這些daemon的啟動(dòng)和退出。
Observer模式,觀察者模式,這個(gè)模式也叫pub-sub模式,很像我們用手機(jī)訂閱手機(jī)報(bào),微博的 follow的信息流也是這樣的一個(gè)模式。MVC中的C會(huì)sub V中的事件,用非OO的方式其實(shí)也是一個(gè)回調(diào)函數(shù)的事。在很多異步系統(tǒng)中,你需要知道最終的調(diào)用有沒(méi)有成功,比如說(shuō)調(diào)用支付寶的支付接口,你需要向支付寶注冊(cè)一個(gè)回調(diào)的接口,以便支付寶回調(diào)你。Linux下的一些系統(tǒng)調(diào)用如epoll/aio/inotify/signal都是這種思路。
Strategy 模式,策略模式,這個(gè)模式和Bridge模式很像,只不過(guò)Bridge是結(jié)構(gòu)模式,其主要是用于對(duì)象的構(gòu)造;而Strategy是行為模式,主要是用于對(duì)象的行為。策略模式很像瀏覽器里的各種插件,只要你裝了某個(gè)插件,你就有某個(gè)功能。你可以安裝多個(gè)插件來(lái)讓你的瀏覽器有更多的功能(書本上的這個(gè)模式是你只能選用一個(gè)算法,當(dāng)然,我們不用那么教條)。就像《你可能不知道的Shell》中的那個(gè)設(shè)置設(shè)置$EDITOR變量后可以按ctrl+x e啟動(dòng)編譯器,或是用set -o vi或set -o emacs 來(lái)讓自己的shell像vi或 emacs 一樣,或是像find -exec或xargs一樣的拼裝命令。
Bridge 和 Strategy是OO設(shè)計(jì)模式里的“Favor Composition Over Inheritance” 的典范,其實(shí)現(xiàn)了接口與實(shí)現(xiàn)分離的。 Unix中的Shell就是一種,你可隨意地更換不同的Shell。還有Emacs中的LISP驅(qū)動(dòng)C,C實(shí)現(xiàn)了引擎,交給LISP實(shí)現(xiàn)邏輯。把程序分為前端和后端,通過(guò)socket專用應(yīng)用協(xié)議進(jìn)行通訊,前端實(shí)現(xiàn)策略,后端實(shí)現(xiàn)機(jī)制。再看看makefile把編譯器和源代碼的解耦,命令行輸出這個(gè)接口可以把一個(gè)復(fù)雜的功能解耦并抽像成各種各樣小而美的小功能命令,等等這樣的例子,你會(huì)發(fā)現(xiàn),還有大量的編程框架都會(huì)多少采用這樣的思想,可以讓你的軟件像更換汽車零件一樣方便。我在用Unix的設(shè)計(jì)思想來(lái)應(yīng)對(duì)變更的需求中說(shuō)過(guò)燈具廠,燈泡廠,和開關(guān)廠的例子。
后記
因?yàn)閷懽鱾}(cāng)促,上面的那些東西,可能會(huì)你讓你覺(jué)得有些牽強(qiáng),那么抱歉了,你可以幫我看看在生活中和 Unix里有沒(méi)有更帥的例子。
不過(guò),我們會(huì)發(fā)現(xiàn)上面OO搞出來(lái)的那么多模式在Unix下看來(lái)好像沒(méi)有那么復(fù)雜,而且Unix下看起來(lái)并沒(méi)有那么多模式,而且Unix中的設(shè)計(jì)模式無(wú)非就是這么幾個(gè)關(guān)鍵詞:單一,簡(jiǎn)潔,模塊,拼裝。我們?cè)賮?lái)看看OO設(shè)計(jì)的兩大準(zhǔn)則:1)鐘情于組合而不是繼承,2)依賴于接口而不是實(shí)現(xiàn)。還有S.O.L.I.D原則也一樣(如果你仔細(xì)觀察,你會(huì)發(fā)現(xiàn)SOLID原則在Unix下也是完美地體現(xiàn))。你看,Unix和OO設(shè)計(jì)模式是不是完美的統(tǒng)一嗎?
我有種強(qiáng)烈的感覺(jué)——Unix對(duì)這些所謂的OO的設(shè)計(jì)模式實(shí)現(xiàn)得更好。因?yàn)閁nix就一條設(shè)計(jì)模式!再次推薦《The Art of Unix Programming》
[[74502]]
餐后甜點(diǎn)
我上面提到了《The Art of Unix Programming》,所以我有必要再談?wù)勥@本書中我中毒最深的一章《模塊性:保持清晰和簡(jiǎn)潔》中所談到的膠合層。
膠合層這一節(jié)中說(shuō)了,我們開發(fā)軟件一般要么Top-Down,要么Bottom-Up,這兩種方法都有好有不好。頂層一般是應(yīng)用邏輯層,底層一般是原語(yǔ)層(我理解為技術(shù)沉淀層,或是技術(shù)基礎(chǔ)層)。自頂向下的開發(fā),你可能會(huì)因?yàn)殚_發(fā)到底層后發(fā)現(xiàn)底層可沉淀的東西越來(lái)越不爽(因?yàn)楸豢赡鼙缓芏鄻I(yè)務(wù)邏輯所侵入),如果自底向上的開發(fā),你可能越到上層你越發(fā)現(xiàn)很多你下面干的基礎(chǔ)上工作有很多用不上(比如干多了)。所以,最好的方式是同時(shí)進(jìn)行,一會(huì)頂層,一會(huì)底層,來(lái)來(lái)回回的開發(fā)——說(shuō)白了就是在開發(fā)中不斷的重構(gòu),邊開發(fā)邊理解邊沉淀。
無(wú)論怎么樣,你會(huì)發(fā)現(xiàn)需要一層膠合層來(lái)膠合業(yè)務(wù)邏輯層和底層原語(yǔ)層(軟件開發(fā)中的業(yè)務(wù)層和技術(shù)層的膠合),Unix的設(shè)計(jì)哲學(xué)認(rèn)為,這層膠合層應(yīng)該盡量地薄,膠合層越多,我們就只能在其中苦苦掙扎。
其實(shí),膠合層原則就是分離原則上更為上層地體現(xiàn),策略(業(yè)務(wù)邏輯)和機(jī)制(基礎(chǔ)技術(shù)或原語(yǔ))的清楚的分離。你可以看到,OO和 Unix都是在做這樣的分離。但是需要注意到的時(shí),OO用抽象接口來(lái)做這個(gè)分離——很多OO的模式中,抽象層太多了,導(dǎo)致膠合層太過(guò)于復(fù)雜了,也就是說(shuō),OO鼓勵(lì)了——“厚重地膠合和復(fù)雜層次”,反而增加了程序的復(fù)雜度(這種情況在惡化中)。而Unix采用的是薄的膠合層,薄地相當(dāng)?shù)膬?yōu)雅。(通過(guò)這段話的描述,我相信你會(huì)明白了《如此理解面向?qū)ο缶幊獭分械膫€(gè)例子——為什么用OO來(lái)實(shí)現(xiàn)會(huì)比用非OO來(lái)實(shí)現(xiàn)更為地惡心——那就是因?yàn)镺O膠合層太復(fù)雜了)
OO的最大的問(wèn)題就——接口復(fù)雜度太高,膠合層太多!(注:Unix編程藝術(shù)這本書里說(shuō)了軟件有三個(gè)復(fù)雜度:代碼量、接口、實(shí)現(xiàn),這三個(gè)東西構(gòu)成了我們的軟件復(fù)雜度)
再送一個(gè)果盤
大家一定記得《SteveY對(duì)Amazon和Google平臺(tái)的長(zhǎng)篇大論》中Amazon中那個(gè)令人非常向往的SOA式的架構(gòu)。因?yàn)橐郧霸贏mazon,有些話不好說(shuō)。現(xiàn)在可以說(shuō)了,我在Amazon里,我個(gè)人對(duì)這個(gè)服務(wù)化的架構(gòu)相當(dāng)?shù)牟淮?,太?fù)雜,復(fù)雜以亂七八糟,方向是好的,想法也是好的,但是這東西和OO一樣,造成大量的接口復(fù)雜度,今天的Amazon,完全沒(méi)人知道各個(gè)服務(wù)是怎么個(gè)調(diào)用的,一團(tuán)亂麻(其內(nèi)部并不像你看到的AWS那么的美妙。注:AWS是非常不錯(cuò)的,是相當(dāng)好的設(shè)計(jì))。
那么我們?cè)趺磥?lái)解決SOA的接口復(fù)雜度問(wèn)題?其實(shí),Unix早就給出了答案——數(shù)據(jù)驅(qū)動(dòng)編程(詳見:《Unix 編程藝術(shù)》的第9.1章),在我離開Amazon的時(shí)候,美國(guó)總部的Principle SDE們?cè)谕虏劢裉霢mazon的SOA架構(gòu),更好的架構(gòu)應(yīng)該是數(shù)據(jù)驅(qū)動(dòng)式的。(今天還在Amazon的同學(xué)可以上內(nèi)網(wǎng)boardcast上看看相關(guān)的 Principle Talk視頻)
(瞎扯一句:這本來(lái)是我想在2012年杭州QCon上的分享的一個(gè)主題,無(wú)奈當(dāng)時(shí)被大會(huì)組織者給拒了,所以只好講了一個(gè)《建一支小團(tuán)隊(duì)》,今天有多人還是不能明白甚至反感我的那個(gè)《小團(tuán)隊(duì)》的演講,但是我相信那是必然的趨勢(shì),就像十年前大家在說(shuō)“程序員只能干到30歲”時(shí),當(dāng)時(shí)的我我卻毫不猶豫地相信十年后,30歲以上的有經(jīng)驗(yàn)的老程序員一定會(huì)成為各個(gè)公司角逐和竟?fàn)幍募t人)