www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 架構(gòu)師社區(qū)
[導(dǎo)讀]“我是舊時(shí)代的殘黨,新時(shí)代沒有承載我的船?!比绻嫦?qū)ο缶幊淌且粋€(gè)人,我猜他自己在不斷被非議的今天,一定會(huì)這樣感慨。說實(shí)話,我用面向?qū)ο蠓绞骄幊桃呀?jīng)十幾年了,我做架構(gòu)設(shè)計(jì)離不開它,做系統(tǒng)分析離不開它,編碼的時(shí)候更是嚴(yán)重依賴它,我對(duì)面向?qū)ο鬅o論是思想上還是寫代碼上都對(duì)它是有很深的感...

“我是舊時(shí)代的殘黨,新時(shí)代沒有承載我的船?!?/p>如果面向?qū)ο缶幊?/a>是一個(gè)人,我猜他自己在不斷被非議的今天,一定會(huì)這樣感慨。

說實(shí)話,我用面向?qū)ο蠓绞骄幊桃呀?jīng)十幾年了,我做架構(gòu)設(shè)計(jì)離不開它,做系統(tǒng)分析離不開它,編碼的時(shí)候更是嚴(yán)重依賴它,我對(duì)面向?qū)ο鬅o論是思想上還是寫代碼上都對(duì)它是有很深的感情。

剛學(xué) Java 的時(shí)候,我覺得面向?qū)ο缶幊蹋∣OP)真牛逼,用面向?qū)ο蠓绞綄懗鰜淼拇a是最好的代碼。但是隨著項(xiàng)目越做越多,代碼越寫越多,我發(fā)現(xiàn) OOP 不是萬能的,盲目的迷信追求 OOP 會(huì)有代價(jià)。

今天這篇文章我不是說面向?qū)ο蟛缓?,只是希望大家不要過度神話它,更不要人云亦云。

大家都聽說過

面向?qū)ο蟮娜筇匦裕豪^承、封裝、多態(tài)

但其實(shí)這個(gè)說法有問題。面向?qū)ο蟮乃枷肜餂]有任何繼承和多態(tài)的概念,正確的說法是:

這三大特性是面向?qū)ο笳Z言的特性,而不是面向?qū)ο罄砟畋旧淼摹?/p>面向?qū)ο笳Z言是面向?qū)ο笤O(shè)計(jì)思想的一種實(shí)現(xiàn),面向?qū)ο笳Z言為了能在真實(shí)世界使用,其必須經(jīng)過一些拓展和妥協(xié),而問題也就隨著這些拓展和妥協(xié)而來。

1. 繼承帶來的也可能是無以復(fù)加的痛苦

在實(shí)際開發(fā)中,我們無論誰寫代碼,都要考慮代碼的復(fù)用性。面向?qū)ο蟮木幊陶Z言作為給開發(fā)人員使用的工具,它也必須考慮到復(fù)用性。

所以,在面向?qū)ο缶幊陶Z言里,對(duì)面向?qū)ο蟮幕A(chǔ)思想做了拓展,搞出了繼承這個(gè)概念。

繼承就具體實(shí)現(xiàn)來說,就是子類擁有父類的所有非 private 的屬性和方法。繼承的出現(xiàn)能夠最大化的代碼復(fù)用。

當(dāng)項(xiàng)目里一個(gè)類已經(jīng)有了我們需要的屬性和方法,而我們現(xiàn)在的需求只是在這個(gè)已有類的基礎(chǔ)上有些許的不同,我們只需要繼承這個(gè)類,僅把這少許的不同在子類中實(shí)現(xiàn)即可。

但是如果你用了繼承,你就引入了問題。

繼承的出現(xiàn)天然會(huì)使得子類和父類緊耦合。也就是說,父類和子類是緊密關(guān)聯(lián)的,牽一發(fā)動(dòng)全身。

如果現(xiàn)實(shí)世界里,所有業(yè)務(wù)模型都是有層次的,而且層次井然有序,是一顆天然的樹,那這種緊耦合沒有什么問題。

但是現(xiàn)實(shí)的需求可不是吃干飯的!

咱們看看這樣一種情況。假設(shè)現(xiàn)在我們一家只有兩口人,即只有父親和孩子,那么類繼承模型很容易模擬這種情況:

我們?cè)诂F(xiàn)實(shí)生活里,往往是三口之家:

那這就有問題了。就像小時(shí)候經(jīng)常有人會(huì)問孩子,你覺得你是爸爸的孩子,還是媽媽的孩子?。咳绻阋?Java 的規(guī)矩回答,只能從是爸爸或者媽媽里選一個(gè),那么完蛋了?;卮鸢职值暮⒆?,媽媽不高興;回答媽媽的孩子,問題更嚴(yán)重,隔壁老王?

但是,如果像 C 那樣,你說我既是爸爸的孩子也是媽媽的孩子,也有問題。

假設(shè)爸爸類里有個(gè)方法叫說話,媽媽類也有個(gè)方法叫說話,你作為繼承了他們的孩子類,自然也會(huì)擁有說話這個(gè)方法。問題來了,你所擁有的的說話這個(gè)方法到底來源于誰?

另外咱們說了,繼承會(huì)把子類和父類緊耦合,一旦業(yè)務(wù)模型失配,就會(huì)造成問題。

這里給出一個(gè)維基百科舉的經(jīng)典例子,來說明一下:

class?Super?{

??private?int?counter?=?0;

??void?inc1()?{
????counter ;
??}

??void?inc2()?{
????counter ;
??}

}

class?Sub?extends?Super?{

??@Override
??void?inc2()?{
????inc1();
??}

}
你看,子類覆蓋了父類的 inc2 方法,但是這個(gè) inc2 方法依賴于父類 inc1 的實(shí)現(xiàn)。

如果父類的 inc1 邏輯發(fā)生變化了,變成下面這樣

class?Super?{

??private?int?counter?=?0;

??void?inc1()?{
????inc2();
??}

??void?inc2()?{
????counter ;
??}
}
這就會(huì)出現(xiàn) stack overflow 的異常,因?yàn)槌霈F(xiàn)了無限遞歸。

所以,當(dāng)我們?cè)谧宇惱?,依賴了父類方法作為子類業(yè)務(wù)邏輯的一個(gè)關(guān)鍵步驟的時(shí)候,當(dāng)父類的邏輯修改的時(shí)候,必須聯(lián)動(dòng)修改所有依賴父類相關(guān)邏輯的子類,否則就可能引發(fā)嚴(yán)重的問題。

用繼承,本來是想少寫點(diǎn)代碼少加點(diǎn)班,結(jié)果……用網(wǎng)上看到的一句話說就是:

一日為父,終生是祖宗。

像這種情況該怎么辦?

現(xiàn)在只要是個(gè)正經(jīng)的介紹面向?qū)ο蟮募夹g(shù)文章或者書籍里,只要是涉及到繼承的,都會(huì)加這么句話:

盡量選擇對(duì)象組合的設(shè)計(jì)方式。

在《阿里巴巴Java開發(fā)手冊(cè)》中就有一條:

組合和繼承的區(qū)別如下:

其實(shí)我認(rèn)為繼承和組合各有優(yōu)缺點(diǎn),如果兩個(gè)類確實(shí)非常緊密,就是存在層次關(guān)系,用繼承沒問題。

之所以有“組合優(yōu)于繼承”這個(gè)說法,我個(gè)人感覺是組合更靈活,而且能防止被人濫用,用不好的話輕則類的層次失控,重則很可能就把整個(gè)項(xiàng)目的代碼質(zhì)量給腐蝕了。

2. 封裝如同帶有漏洞的封印,可能會(huì)逃逸出魔王

封裝,說白了就是把屬性、方法,封到一個(gè)對(duì)象里,這是面向?qū)ο蟮暮诵睦砟睢?/p>嘴上叫封裝,卻開了個(gè)縫兒。

我們知道,項(xiàng)目是既要兼顧代碼質(zhì)量,還要兼顧運(yùn)行性能的。不可能說為了提升什么松耦合、高內(nèi)聚,就不管不顧性能了。

事情就壞在了這個(gè)兼顧性能這里。面向?qū)ο罄?,以上帝角度看,系統(tǒng)就是對(duì)象和對(duì)象之間的關(guān)系構(gòu)造成的網(wǎng)絡(luò)。

就拿咱們上面談到的組合關(guān)系來說,組合關(guān)系的實(shí)現(xiàn)就是通過把一個(gè)對(duì)象當(dāng)成另一個(gè)對(duì)象的屬性來實(shí)現(xiàn)的。

上面這圖就叫做 A 和 B 之間是組合關(guān)系。想用 A 對(duì)象里的 B 對(duì)象,代碼這么寫:

A?a?=?new?A();
B?b?=?a.getB();
好,我們要問了,這個(gè)從 A 中獲取的 B,是 B 對(duì)象的實(shí)例還是實(shí)例的一個(gè)引用指針呢?

必然是引用指針吧,這是最基礎(chǔ)的知識(shí)。諾,問題來了,引用指針是可以修改的。

b.getS();?//原來是Hello?World
b.setS("World");//直接改成World
原來 B 中有個(gè)字段 s,值是個(gè) “Hello World”,我直接可以用代碼改成“World”。

如果這次修改隨意在個(gè)犄角旮旯里,A 能知道嗎?A 蒙在鼓里,還以為一切盡在把控當(dāng)中呢。

你看,封裝的縫兒出來了吧。說句實(shí)話,就這種鬼操作,是非常難以排查的。

像這種封裝了,但是又沒封裝的問題,我只想說“封裝的挺好的,下次別封裝了”。

3. 多態(tài)好,但可能是面向?qū)ο蟮呢澨熘?/h2>再說說多態(tài)。

其實(shí),面向?qū)ο笾械亩鄳B(tài)使用,才是面向?qū)ο笳Z言最被認(rèn)可的地方。因?yàn)橛辛硕鄳B(tài),代碼才能保證在業(yè)務(wù)需求多變的情況下,保證了項(xiàng)目的相對(duì)穩(wěn)定。

可是,多態(tài)不是面向?qū)ο螵?dú)有的啊。面向過程,函數(shù)式編程也可以:面向過程里,C 語言可以靠虛函數(shù)去在運(yùn)行時(shí)加載對(duì)應(yīng)的函數(shù)實(shí)現(xiàn)去實(shí)現(xiàn)多態(tài)。函數(shù)式編程也可以通過組合函數(shù)去實(shí)現(xiàn)多態(tài)。

所以,面向?qū)ο筮B多態(tài)這種優(yōu)勢(shì)都不獨(dú)特了。

4. 服務(wù)端業(yè)務(wù)變了,人們的觀點(diǎn)發(fā)生變化了

在說服務(wù)端業(yè)務(wù)的變化之前,我想先普及兩個(gè)概念,即有狀態(tài)的服務(wù)和無狀態(tài)的服務(wù)。

有狀態(tài)的服務(wù)就是說,服務(wù)需要暫時(shí)存一些和客戶端相關(guān)的數(shù)據(jù),以便客戶端后續(xù)發(fā)來的請(qǐng)求可以和客戶端前面發(fā)的請(qǐng)求通過服務(wù)器端關(guān)聯(lián)起來,從而共同完成一項(xiàng)業(yè)務(wù)。

無狀態(tài)服務(wù)是說,服務(wù)端不存儲(chǔ)任何和客戶端相關(guān)的數(shù)據(jù),客戶端每次請(qǐng)求,服務(wù)端都認(rèn)為這是個(gè)新客戶端,和以前的請(qǐng)求無任何關(guān)系。

用現(xiàn)實(shí)生活舉例的話,有狀態(tài)服務(wù)就是你去一家健身房,第一次去的時(shí)候花了一筆錢辦了一張健身卡,你以后每次去健身,有卡就不用再掏錢了。

無狀態(tài)服務(wù)就是,你沒辦卡,每次去都和第一次去一樣現(xiàn)掏錢。

那么,無狀態(tài)服務(wù)和有狀態(tài)服務(wù)和面向?qū)ο蟮乃ヂ溆钟惺裁搓P(guān)系呢?在如今的年代,分布式、微服務(wù)大行其道。一個(gè)有狀態(tài)的服務(wù)是不容易做分布式和做彈性伸縮的。

當(dāng)年,大家做有多個(gè)步驟的業(yè)務(wù)的時(shí)候,為了保證業(yè)務(wù)數(shù)據(jù)不會(huì)因?yàn)橛脩襞既坏年P(guān)閉瀏覽器或者瀏覽器崩潰等問題而丟失,往往會(huì)把上一個(gè)步驟的信息存在服務(wù)端的 session 里,而現(xiàn)在則會(huì)傾向考慮把信息放在客戶端的本地存儲(chǔ)上。

我舉個(gè)例子,假設(shè)現(xiàn)在有個(gè)需求,要在后臺(tái)系統(tǒng)新增加一個(gè)功能:用戶信息管理。其中有個(gè)需求要求這樣操作,錄入用戶信息分成兩步。

  • 第一步,錄入用戶的基本信息:姓名、手機(jī)號(hào)、年齡……

  • 第二步,錄入額外信息:家庭成員、教育經(jīng)歷、工作經(jīng)歷……

出于信息完整度的考慮,業(yè)務(wù)要求這兩步應(yīng)該是一個(gè)完整的事務(wù)。要么都成功,要么都失敗。

從技術(shù)實(shí)現(xiàn)上講,如果是多年以前,我們會(huì)在第一步的時(shí)候,把商戶的基本信息做成表單提交,然后為了保證不會(huì)因?yàn)橛脩粽`關(guān)閉瀏覽器等意外問題丟失中間的數(shù)據(jù),保存在對(duì)應(yīng)的 session 中后,在第二步信息提交后,合并起來一起存入到數(shù)據(jù)庫(kù)中。

但是,現(xiàn)在的技術(shù)趨勢(shì)是,做任何事情,盡量讓服務(wù)器端無狀態(tài),也就是不存儲(chǔ)客戶端相關(guān)數(shù)據(jù)。

此時(shí),這個(gè)需求的解決方案就是,當(dāng)?shù)谝徊教顚懮虘粜畔⑼瓿珊?,直接把?shù)據(jù)存儲(chǔ)在客戶端的本地存儲(chǔ)里又或者直接就存在 cookie 里,在第二步填寫內(nèi)容完畢后,聯(lián)合存在客戶端的信息一起提交到服務(wù)器端,然后存入數(shù)據(jù)庫(kù)。

所以,你看到了,現(xiàn)在大家的趨勢(shì)就是服務(wù)器端都在轉(zhuǎn)向無狀態(tài)服務(wù),哪怕以前是有狀態(tài)的服務(wù),也會(huì)通過一些增加客戶端參數(shù)等手段,去改造為無狀態(tài)服務(wù)。

說了這么多,那這種技術(shù)趨勢(shì)的變化對(duì)我們的面向?qū)ο笥惺裁从绊懩兀?/p>影響在于,服務(wù)端現(xiàn)在越來越變得往單純的處理數(shù)據(jù)這個(gè)方向發(fā)展。當(dāng)僅處理數(shù)據(jù)的時(shí)候,服務(wù)器端真正的需求其實(shí)就是計(jì)算,然后就是為了大幅度提升計(jì)算速度,而帶來的并行化需求。

而面向?qū)ο筮@種方式和我們當(dāng)今的技術(shù)趨勢(shì)是有一些沖突的。

首先就是確定性的沖突。

我們的首要需求從以前重度處理業(yè)務(wù)狀態(tài)加業(yè)務(wù)數(shù)據(jù)變成了業(yè)務(wù)數(shù)據(jù)的計(jì)算,而計(jì)算是需要確定性的:即給定相同的輸入,經(jīng)過服務(wù)器端相同的邏輯處理后,應(yīng)該給定相同的輸出。

而面向?qū)ο筮@種方式,出身在有狀態(tài)服務(wù)大行其道的年代,它會(huì)優(yōu)先考慮業(yè)務(wù)邏輯的調(diào)度,其次才是計(jì)算,所以,面向?qū)ο笫菗碛袪顟B(tài)的。面向?qū)ο蟮臓顟B(tài)就是它的字段值。這些字段值,如果單純的從計(jì)算數(shù)據(jù)角度看,他們不僅無意義了,反而還引入了風(fēng)險(xiǎn)。

比如,我們不小心把一個(gè)對(duì)象的狀態(tài)給共享出去了,那當(dāng)我們用同樣的輸入計(jì)算的時(shí)候,很可能由于狀態(tài)的變化,導(dǎo)致了不同的輸出結(jié)果,最后就是項(xiàng)目出了問題。

其次,由于計(jì)算我們對(duì)性能更加看重了,又由于無狀態(tài)服務(wù)的大量使用,所以,并行的重要性也遠(yuǎn)遠(yuǎn)超出了以前。而并行,要求的是結(jié)構(gòu)的開放,和更加嚴(yán)格的無狀態(tài)化,而面向?qū)ο?,恰恰?yán)重依賴于狀態(tài),并且,他還把這種狀態(tài)依賴封裝在了復(fù)雜的對(duì)象關(guān)系里。

A 狀態(tài)依賴于 B 的狀態(tài),B 的狀態(tài)又依賴于 C,而這些依賴,全部被封裝在了 D 對(duì)象的實(shí)現(xiàn)細(xì)節(jié)里,這種嚴(yán)重的反并行也是現(xiàn)在越來越多人開始反感面向?qū)ο蟮闹匾颉?/p>

結(jié)尾

說了這么多面向?qū)ο蟮膲脑?,其?shí)真的是面向?qū)ο笞陨淼膯栴}嗎?并不是。

首先,面向?qū)ο笃鋵?shí)就是我們程序員試圖簡(jiǎn)化這個(gè)世界,提高對(duì)這個(gè)世界的認(rèn)知的一種美好愿望而已。愿望來自于人自身認(rèn)知的局限性,所以本身就不可能完美。

其次,
面向?qū)ο缶幊?/a>語言只是一種工具,工具的使用的好壞還是要靠人的,不可能每個(gè)人能把一套工具用的完美無缺。

如上所說,面向?qū)ο蟮膯栴}本質(zhì)還是人的問題,而人可能永遠(yuǎn)都需要通過組合使用越來越多的類似面向?qū)ο蟮倪@種并不完美的工具去解決自己的問題。

所以,我們不能一味的依靠面向?qū)ο?,認(rèn)為面向?qū)ο缶褪亲畎舻?,也不能發(fā)現(xiàn)面向?qū)ο罂赡軕?yīng)付不了某些業(yè)務(wù)場(chǎng)景了,就開始極端地摒棄它。

我們要靈活地,合理地使用任何我們可以使用的編程思想、編程工具,積極地去擁抱變化。

不要忘了我們寫代碼的初衷。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉