摘要與說明:因篇幅稍長,以下觀點卸伞,您若認(rèn)可或完全不能接受抹镊,可以略過此文。如果您感興趣荤傲,請耐心閱讀垮耳,歡迎不同意見。
要點1.“復(fù)用軟件更像是器官移植而不是拼裝樂高積木”遂黍, 也就是說终佛,表面上看起來兩個人的器官功能一樣,但實際上有細(xì)微的差異雾家,這就會導(dǎo)致移植后的排異反應(yīng)铃彰,必須靠不停吃藥來維持。
要點2.代碼復(fù)用或功能復(fù)用很好芯咧,但不能濫用牙捉。復(fù)用微服務(wù)層級的功能所帶來的好處是虛幻的。
在二十多年前敬飒,當(dāng)我在大學(xué)剛開始學(xué)習(xí)編程的時候邪铲,老師、課本无拗、語言的發(fā)明者都教導(dǎo)我要“重用”或者“復(fù)用”代碼或者程序带到,這樣我們的程序就會像拼積木那樣迅速造出更多高級的東西。在我們的編程生涯中英染,我們以不同的形式來復(fù)用或重用代碼揽惹。在面向過程語言中晌纫,我們提煉“公共函數(shù)(function)庫”,在面向?qū)ο笳Z言出現(xiàn)后永丝,我們開始提煉 “公共對象庫”。現(xiàn)在箭养,微服務(wù)概念出現(xiàn)之后慕嚷,我們又開始提煉“共享的服務(wù)中心”,這樣一路下來毕泌,大家都覺得順理成章喝检。我相信,很多人都和我一樣有過這樣的經(jīng)歷和想法撼泛,并且曾經(jīng)深信不移挠说。可以說“復(fù)用\重用”的思想已經(jīng)深深地根植于每個程序員的意識之中愿题。
當(dāng)前损俭,國內(nèi)流行的“中臺架構(gòu)”特別倡導(dǎo)建設(shè)“共享服務(wù)中心”,復(fù)用“共享服務(wù)中心”內(nèi)沉淀的服務(wù)潘酗,這是傳統(tǒng)SOA的架構(gòu)思想杆兵,這種想法來自于單體應(yīng)用的時代我們對代碼復(fù)用的慣性思維。但在微服務(wù)時代仔夺,繼續(xù)在微服務(wù)服務(wù)級別沿用這種“代碼或這功能復(fù)用”的思維會特別地有害琐脏,主要的問題就是會產(chǎn)生“上帝式服務(wù)”,如果這個“上帝服務(wù)”不穩(wěn)定缸兔,那么整個系統(tǒng)就會不穩(wěn)定日裙,這就要求上帝式服務(wù)必須特別穩(wěn)定,而在企業(yè)的業(yè)務(wù)系統(tǒng)中惰蜜,穩(wěn)定的業(yè)務(wù)服務(wù)提煉的難度和代價特別高昂拂,甚至只是理論上存在而現(xiàn)實很難實現(xiàn)。
但是蝎抽,由于傳統(tǒng)思維如此強(qiáng)勢并占主導(dǎo)地位政钟。如果有人說“復(fù)用\重用“的思想有問題,那么很多人肯定會感覺吃驚樟结,或者覺得這是“無稽之談”而不以為意养交,甚至還可能認(rèn)為這是故意制造驚世駭俗的言論或想成為網(wǎng)紅而制造熱點。但是正如《演進(jìn)式架構(gòu)》一書所說的那樣:“復(fù)用代碼顯然很好瓢宦,然而任何美好事物都不能被濫用”碎连,該書中還引用了John.D.Cook博士的話:“復(fù)用軟件更像是器官移植而不是拼裝樂高積木”⊥月模可見鱼辙,“復(fù)用代碼”并非總是好的廉嚼,甚至可能危害巨大,想像一下“內(nèi)臟移植”的排異反應(yīng)能理解John.D.Cook博士的警告了倒戏。也就是說怠噪,表面上看起來兩個人的器官功能一樣,但實際上有致命性的細(xì)微差異杜跷,這就會導(dǎo)致移植后的排異反應(yīng)傍念,必須靠不停吃藥來維持。我們對業(yè)務(wù)和領(lǐng)域的理解未必能夠足夠透徹葛闷,所以“功能復(fù)用”的濫用就會導(dǎo)致排異反應(yīng)憋槐。
樂高積木則不然,樂高積木組件的功能單一淑趾,相同功能組件之間不存在致命性的細(xì)微差異阳仔。所以我們?nèi)绻非蟠a的復(fù)用性那么這塊代碼的功能就必須足夠存粹和單一,代碼的復(fù)用性越高扣泊,它所能實現(xiàn)的功能就越單一近范,推論到極致就是我們復(fù)用最多功能包括+ - * \ = ,因為你可以將它們看成操作函數(shù)延蟹,雖然復(fù)用性高了顺又,但是可用性確實降低了,因為一條“加法語句”幾乎完成不了什么軟件功能等孵。對于領(lǐng)域軟件開發(fā)者而言稚照,代碼復(fù)用性越高,就越會失去領(lǐng)域的功能與特性俯萌」迹可以說,能夠被廣泛復(fù)用的代碼都是軟件業(yè)的“標(biāo)準(zhǔn)件”咐熙,比如Log4j弱恒。就像機(jī)械行業(yè)的“標(biāo)準(zhǔn)螺釘,螺母”等棋恼。雖然標(biāo)準(zhǔn)件被廣發(fā)使用返弹,但是它的用途就是那么單一,因而無論軟件業(yè)還是機(jī)械行業(yè)爪飘,相對行業(yè)所有組件而言义起,標(biāo)準(zhǔn)件的種類還是不多,都是遠(yuǎn)遠(yuǎn)少于專業(yè)組件师崎,就是因為高可用的復(fù)雜零件甚難通用默终。因而,《演進(jìn)式架構(gòu)》一書告訴我們的“代碼復(fù)用性越高,其可用性越低”齐蔽。所以两疚,對復(fù)用性的追求應(yīng)有個合適的限度。
當(dāng)然含滴,和使用樂高積木一樣诱渤,我們復(fù)用標(biāo)準(zhǔn)件問題不大,因為它們的功能單一谈况,所以穩(wěn)定源哩,就像Log4j庫,java的String鸦做、Collection庫等,它們其實發(fā)展了很多年谓着,甚至在其他古老語言中已經(jīng)積累了足夠的經(jīng)驗和教訓(xùn)泼诱。如果我們沒有足夠的經(jīng)驗,盡量不要試圖一次性提煉出共享的服務(wù)讓所有人復(fù)用赊锚,這不僅成本和代價巨大治筒,而且后遺癥嚴(yán)重。因為舷蒲,我們復(fù)用了別人的代碼耸袜,就意味著在我們的功能(身體)里耦合了別人的功能(器官)。
回想一下牲平,我們所復(fù)用的那些通用的功能堤框,基本上都是來自開源的跨業(yè)務(wù)領(lǐng)域的通用功能代碼庫。我們真的復(fù)用身邊同事所寫的共享的業(yè)務(wù)功能了嗎纵柿?我的答案是很少很少蜈抓,這是不是難以置信?與我們的直覺不符昂儒?因為我們感覺自己使用了很多其他同事的類沟使,大家在協(xié)同工作,雖然共享范圍不是那么廣渊跋,但總是在復(fù)用別人的類庫腊嗡。好吧,仔細(xì)品味一下拾酝,我們大多數(shù)的情況下都是在利用別的同事類庫中的數(shù)據(jù)模型或數(shù)據(jù)來完成自己所負(fù)責(zé)的數(shù)據(jù)處理功能燕少。所以,函數(shù)式編程強(qiáng)調(diào)把數(shù)據(jù)與代碼分離蒿囤。感興趣的話棺亭,可以看看《FUNCTIONAL AND REACTIVE DOMAIN MODELING》(中文版《函數(shù)響應(yīng)式領(lǐng)域建模》),關(guān)于“數(shù)據(jù)與代碼”分離這一點镶摘,以后有機(jī)會討論“面向?qū)ο缶幊讨小皩ο蟪橄蟆钡母拍钤龠M(jìn)一步闡述嗽桩。
總之,代碼復(fù)用或者功能服務(wù)用會帶來耦合凄敢,復(fù)用越多耦合越多碌冶,傳統(tǒng)SOA架構(gòu)理念所提倡的服務(wù)復(fù)用思想不再適用于數(shù)字化時代的系統(tǒng)架構(gòu)。共享服務(wù)中心或者共享能力中心都是傳統(tǒng)SOA架構(gòu)理念的產(chǎn)物涝缝,在數(shù)字化時代采用微服務(wù)架構(gòu)配合流式計算更適合大型企業(yè)扑庞。