精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

系統(tǒng)困境與軟件復(fù)雜度,為什么我們的系統(tǒng)會如此復(fù)雜

開發(fā) 架構(gòu)
讀 A Philosophy of Software Design 有感,軟件設(shè)計與架構(gòu)復(fù)雜度,你是戰(zhàn)術(shù)龍卷風(fēng)嗎?

一、前言

有一天,一個醫(yī)生和一個土木工程師在一起爭論“誰是世界上最古老的職業(yè)”。醫(yī)生說:“上帝用亞當(dāng)?shù)睦吖窃斐隽讼耐蓿@是歷史上第一次外科手術(shù),所以最古老的職業(yè)應(yīng)該是醫(yī)生”,土木工程師說:“在創(chuàng)世紀(jì)之前,上帝從混沌中創(chuàng)造了天堂與人間,這是更早之前的一次土木作業(yè),所以最古老的職業(yè)應(yīng)該是土木工程”。這時軟件工程師拖著鍵盤走出來說,“那你認(rèn)為,是誰創(chuàng)造了那片混沌?”

建筑師不會輕易給100層的高樓增加一個地下室,但我們卻經(jīng)常在干這樣的事,并且總有人會對你說,“這個需求很簡單”。到土里埋個地雷,這確實不復(fù)雜,但我們往往面臨的真實場景其實是:“在這片雷區(qū)里加一個雷”,而雷區(qū)里哪里有雷,任何人都不知道 。

二、什么是復(fù)雜性

我們一直在說系統(tǒng)很復(fù)雜,那到底什么是復(fù)雜性?關(guān)于復(fù)雜的定義有很多種,其中比較有代表的是Thomas J. McCabe 在1976提出的理性派的復(fù)雜性度量,與John Ousterhout 教授提出的感性派的復(fù)雜性認(rèn)知。

1.理性度量

復(fù)雜性并不是什么新概念,早在上世紀(jì)70年代,軟件就已經(jīng)極其復(fù)雜,開發(fā)與維護(hù)的成本都非常高。1976年McCabe&Associates公司開始對軟件進(jìn)行結(jié)構(gòu)測試,并提出了McCabe Cyclomatic Complexity Metric,我們也稱之為McCabe圈復(fù)雜度。它通過多個維度來度量軟件的復(fù)雜度,從而判斷軟件當(dāng)前的開發(fā)/維護(hù)成本。

圈復(fù)雜度

代碼狀況

測性成本

維護(hù)成本

圈復(fù)雜度1 - 10

清晰/結(jié)構(gòu)化

可測性高

維護(hù)成本低

圈復(fù)雜度10 - 20

復(fù)雜

可測性中

維護(hù)成本中

圈復(fù)雜度20 - 30

非常復(fù)雜

可測性低

維護(hù)成本高

圈復(fù)雜度30

不可讀

不可測

維護(hù)成本非常高

2.感性認(rèn)知

復(fù)雜度高的代碼一定不是好代碼,但復(fù)雜度低的也不一定就是好代碼。John Ousterhout教授認(rèn)為軟件的復(fù)雜性相對理性的分析,可能更偏感性的認(rèn)知。

Complexity is anything that makes software hard to understand or to modify

-- John Ousterhout 《A Philosophy of Software Design》

譯:所謂復(fù)雜性,就是任何使得軟件難于理解和修改的因素。

50年后的今天,John Ousterhout教授在 A Philosophy of Software Design 書中提到了一個非常主觀的見解,復(fù)雜性就是任何使得軟件難于理解和修改的因素。

模糊性與依賴性是引起復(fù)雜性的2個主要因素,模糊性產(chǎn)生了最直接的復(fù)雜度,讓我們很難讀懂代碼真正想表達(dá)的含義,無法讀懂這些代碼,也就意味著我們更難去改變它。而依賴性又導(dǎo)致了復(fù)雜性不斷傳遞,不斷外溢的復(fù)雜性最終導(dǎo)致系統(tǒng)的無限腐化,一旦代碼變成意大利面條,幾乎不可能修復(fù),成本將成指數(shù)倍增長。

三、復(fù)雜性的表現(xiàn)形式

復(fù)雜的系統(tǒng)往往也有一些非常明顯的特征,John教授將它抽象為變更放大(Change amplification)、認(rèn)知負(fù)荷(Cognitive load)與未知的未知(Unknown unknowns)這3類。當(dāng)我們的系統(tǒng)出現(xiàn)這3個特征,說明我們的系統(tǒng)已經(jīng)開始逐漸變得復(fù)雜了。

癥狀1-變更放大

Change amplification: a seemingly simple change requires code modifications in many different places.

-- John Ousterhout 《A Philosophy of Software Design》

譯:看似簡單的變更需要在許多不同地方進(jìn)行代碼修改。

變更放大(Change amplification)指得是看似簡單的變更需要在許多不同地方進(jìn)行代碼修改。比較典型的代表是Ctrl-CV式代碼開發(fā),領(lǐng)域模型缺少內(nèi)聚與收攏,當(dāng)需要對某段業(yè)務(wù)進(jìn)行調(diào)整時,需要改動多個模塊以適應(yīng)業(yè)務(wù)的發(fā)展。

/**
* 銷售撿入客戶
*/
public void pick(String salesId, String customerId) {
// 查詢客戶總數(shù)
long customerCnt = customerDao.findCustomerCount(salesId);
// 查詢銷售庫容
long capacity = capacityDao.findSalesCapacity(salesId);
// 判斷是否超額
if(customerCnt >= capacity) {
throws new BizException("capacity over limit");
}
// 代碼省略 do customer pick
}

在CRM領(lǐng)域,銷售撿入客戶時需要進(jìn)行庫容判斷,這段代碼也確實可以滿足需求。但隨著業(yè)務(wù)的發(fā)展,簽約的客戶要調(diào)整為不占庫容。而客戶除了銷售撿入,還包括主管分發(fā)、leads分發(fā)、手工錄入、數(shù)據(jù)采買等多個場景,如果沒對庫容域做模型的收攏,一個簡單的邏輯調(diào)整,就需要我們在多個場景做適配才能滿足訴求。

癥狀2-認(rèn)知負(fù)荷

Cognitive load: how much a developer needs to know in order to complete a task.

-- John Ousterhout 《A Philosophy of Software Design》

譯:開發(fā)人員需要多少知識才能完成一項任務(wù)。

認(rèn)知負(fù)荷(Cognitive load)是指開發(fā)人員需要多少知識才能完成一項任務(wù)。使用功能性框架時,我們希望它操作簡單,部署復(fù)雜系統(tǒng)時,我們希望它架構(gòu)清晰,其實都是降低一項任務(wù)所需的成本。盲目的追求高端技術(shù),設(shè)計復(fù)雜系統(tǒng),增加學(xué)習(xí)與理解成本都屬于本末倒置的一種。

TMF是整個星環(huán)的支柱,也是業(yè)務(wù)中臺面向可復(fù)用可擴(kuò)展架構(gòu)的核心。但TMF太過復(fù)雜,認(rèn)知與學(xué)習(xí)成本非常高,我們?nèi)粘V兴媾R的一些擴(kuò)展訴求99%(或者應(yīng)該說100%)都不適合TMF,可能通過一些設(shè)計模式或者就是一些if else,可能更適合解決我們的問題。

除此之外,還包括一些簡單搜索場景卻用到了blink等流式引擎,簡單后臺系統(tǒng)通過DDD進(jìn)行構(gòu)建,幾個商品發(fā)布的狀態(tài)機(jī)轉(zhuǎn)換用上了規(guī)則引擎等等,都屬于認(rèn)知負(fù)荷復(fù)雜度的一種。

癥狀3-未知的未知

Unknown unknowns: it is not obvious which pieces of code must be modified to complete a task

-- John Ousterhout 《A Philosophy of Software Design》

譯:必須修改哪些代碼才能完成任務(wù)。

未知的未知(Unknown unknowns)是指必須修改哪些代碼才能完成任務(wù),或者說開發(fā)人員必須獲得哪些信息才能成功地執(zhí)行任務(wù)。這一項也是John Ousterhout教授認(rèn)為復(fù)雜性中最糟糕的一個表現(xiàn)形式。

當(dāng)你維護(hù)一個有20年歷史的項目時,這種問題的出來相對而言就沒那么意外。由于代碼的混亂與文檔的缺失,導(dǎo)致你無法掌控一個500萬行代碼的應(yīng)用,并且代碼本身也沒有明顯表現(xiàn)出它們應(yīng)該要闡述的內(nèi)容。這時“未知的未知”出現(xiàn)了,你不知道改動的這行代碼是否能讓程序正常運(yùn)轉(zhuǎn),也不知道這行代碼的改動是否又會引發(fā)新的問題。這時候我們發(fā)現(xiàn),那些“上帝類”真的就只有上帝能拯救了。

四、為什么會產(chǎn)生復(fù)雜性

那軟件為什么越來越復(fù)雜,是不是減少一些犯錯就能避免一場浩劫呢?回顧那些復(fù)雜的系統(tǒng),我們可以找到很多因素導(dǎo)致系統(tǒng)腐化。

  • 想簡單圖省事,沒有及時治理不合理的內(nèi)容
  • 缺少匠心追求,對骯臟代碼視而不見
  • 技術(shù)能力不夠,無法應(yīng)對復(fù)雜系統(tǒng)
  • 交接過渡缺失,三無產(chǎn)品幾乎無法維護(hù)

除了上述內(nèi)容外,還可以想到很多理由。但我們發(fā)現(xiàn)他們好像有一個共同的指向點(diǎn) - 軟件工程師,似乎所有復(fù)雜的源頭就是軟件工程師的不合格導(dǎo)致,所以其實一些罪惡的根因是我們自己?

1.統(tǒng)一的中國與分裂的歐洲

歐洲大陸面積大體與中國相當(dāng),但為什么歐洲是分裂的,而中國是統(tǒng)一的。有人說他們文化不一樣,也有人說他們語言不通是主要原因,也有人說他們?nèi)币粋€秦始皇。其實我們回顧歐洲的歷史,歐洲還真不缺一個大一統(tǒng)的帝國。羅馬帝國曾經(jīng)讓地中海成為自己的內(nèi)海,拿破侖鼎盛時期掌管著1300萬平方公里的領(lǐng)地。歐洲也曾出現(xiàn)過偉大的帝國,但都未走向統(tǒng)一。

我們再觀察地圖,其實除了中國、俄羅斯以外,全世界99%的國家都是小國。分裂才是常態(tài),統(tǒng)一才不正常。馬老師也曾說過,成功都有偶然性只有失敗才存在必然。只有極少國家才實現(xiàn)了大一統(tǒng),所以我們不應(yīng)該問為什么歐洲是分裂的,而應(yīng)該問為什么中國是統(tǒng)一的。類比到我們的軟件也同樣如此,復(fù)雜才是常態(tài),不復(fù)雜才不正常。

2.軟件固有的復(fù)雜性

The Complexity of software is an essential property, not an accidental one.

-- Grady Booch 《Object-Oriented Analysis and Design with Applications》

譯:軟件的復(fù)雜性是一個基本特征,而不是偶然如此。

Grady Booch在 Object-Oriented Analysis and Design with Applications 中提出這樣一個觀念,他認(rèn)為軟件的復(fù)雜性是固有的,包括問題域的復(fù)雜性、管理開發(fā)過程的困難性、通過軟件可能實現(xiàn)的靈活性與刻畫離散系統(tǒng)行為的問題,這4個方面來分析了軟件的發(fā)展一定伴隨著復(fù)雜,這是軟件工程這本科學(xué)所必然伴隨的一個特性。

Everything, without exception, requires additional energy and order to maintain itself. I knew this in the abstract as the famous second law of thermodynamics, which states that everything is falling apart slowly.

-- Kevin Kelly 《The Inevitable》

譯:世間萬物都需要額外的能量和秩序來維持自身,無一例外。這就是著名的熱力學(xué)第二定律,即所有的事務(wù)都在緩慢地分崩離析。

Kevin Kelly在 The Inevitable 也有提過類似的觀點(diǎn),他認(rèn)為世間萬物都需要額外的能量和秩序來維持自身,所有的事物都在緩慢地分崩離析。沒有外部力量的注入事物就會逐漸崩潰,這是世間萬物的規(guī)律,而非我們哪里做得不對。

五、軟件架構(gòu)治理復(fù)雜度

為軟件系統(tǒng)注入的外力就是我們的軟件架構(gòu),以及我們未來的每一行代碼。軟件架構(gòu)有很多種,從最早的單體架構(gòu),到后面的分布式架構(gòu)、SOA、微服務(wù)、FaaS、ServiceMesh等等。所有的軟件架構(gòu)萬變不離其宗,都在致力解決軟件的復(fù)雜性。

1.架構(gòu)的本質(zhì)

編程范式指的是程序的編寫模式,軟件架構(gòu)發(fā)展到今天只出現(xiàn)過3種編程范式( paradigm ),分別是結(jié)構(gòu)化編程,面向?qū)ο缶幊膛c函數(shù)式編程。

  • 結(jié)構(gòu)化編程取消 goto 移除跳轉(zhuǎn)語句,對程序控制權(quán)的直接轉(zhuǎn)移進(jìn)行了限制和規(guī)范
  • 面向?qū)ο缶幊滔拗?指針 的使用,對程序控制權(quán)的間接轉(zhuǎn)移進(jìn)行了限制和規(guī)范
  • 函數(shù)式編程以 λ演算法 為核心思想,對程序中的賦值進(jìn)行了限制和規(guī)范

面向?qū)ο蟮奈宕笤O(shè)計原則 S.O.L.I.D。依賴倒置限制了模塊的依賴順序、單一職責(zé)限制模塊的職責(zé)范圍、接口隔離限制接口的提供形式。

軟件的本質(zhì)是約束。商品的代碼不能寫在訂單域,數(shù)據(jù)層的方法不能寫在業(yè)務(wù)層。70年的軟件發(fā)展,并沒有告訴我們應(yīng)該怎么做,而是教會了我們不該做什么。

2.遞增的復(fù)雜性

軟件的復(fù)雜性不會憑空消失,并且會逐級遞增。針對遞增的復(fù)雜性有3個觀點(diǎn):

  • 模糊性創(chuàng)造了復(fù)雜,依賴性傳播了復(fù)雜
  • 復(fù)雜性往往不是由單個災(zāi)難引起的
  • 我們可以容易地說服自己,當(dāng)前變更帶來的一點(diǎn)點(diǎn)復(fù)雜性沒什么大不了

曾經(jīng)小李跟我抱怨,說這段代碼實在是太惡心了,花了很長時間才看懂,并且代碼非常僵硬,而正好這個需求需要改動到這里,代碼真的就像一坨亂麻。我問他最后是怎么處理的,他說,我給它又加了一坨。

3.編程思維論

戰(zhàn)術(shù)編程

其實小李的這種做法并非是一個個體行為,或許我們在遇到復(fù)雜代碼時都曾這樣茍且過,John教授這種編程方法稱之為“戰(zhàn)術(shù)編程”。戰(zhàn)術(shù)編程最主要的特點(diǎn)是快,同時具備如下幾個特點(diǎn)。

  • 當(dāng)前一定是最快的
  • 不會花費(fèi)太多時間來尋找最佳設(shè)計
  • 每個編程任務(wù)都會引入一些復(fù)雜度
  • 重構(gòu)會減慢當(dāng)前任務(wù)速度,所以保持最快速度
@HSFProvider(serviceInterface = AgnDistributeRuleConfigQueryService.class)
public class AgnDistributeRuleConfigQueryServiceImpl implements AgnDistributeRuleConfigQueryService {

@Override
public ResultModel<AgnDistributeRuleConfigDto> queryAgnDistributeRuleConfigById(String id) {
logger.info("queryAgnDistributeRuleConfigById id=" + id);
ResultModel<AgnDistributeRuleConfigDto> result = new ResultModel<AgnDistributeRuleConfigDto>();
if(StringUtils.isBlank(id)){
result.setSuccess(false);
result.setErrorMsg("id cannot be blank");
return result
}
try {
AgnDistributeRuleConfigDto agnDistributeRuleConfigDto = new AgnDistributeRuleConfigDto();
AgnDistributeRuleConfig agnDistributeRuleConfig = agnDistributeRuleConfigMapper.selectById(id);
if(agnDistributeRuleConfig == null){
logger.error("agnDistributeRuleConfig is null");
result.setSuccess(false);
result.setErrorMsg("agnDistributeRuleConfig is null");
return result
}
this.filterDynamicRule(agnDistributeRuleConfig);
BeanUtils.copyProperties(agnDistributeRuleConfig, agnDistributeRuleConfigDto);
result.setSuccess(true);
result.setTotal(1);
result.setValues(agnDistributeRuleConfigDto);
} catch (Exception e) {
logger.error("queryAgnDistributeRuleConfigById error,", e);
result.setSuccess(false);
result.setErrorMsg(e.getMessage());
}
return result;
}
}

我們看上面這段代碼,是一段查詢分發(fā)規(guī)則的業(yè)務(wù)邏輯。雖然功能能夠work,但不規(guī)范的地方其實非常多

  • Facade層定義全部邏輯 - 未做結(jié)構(gòu)分層
  • 業(yè)務(wù)與技術(shù)未做分離 - 耦合接口信息與業(yè)務(wù)數(shù)據(jù)
  • Try catch 滿天飛 - 缺少統(tǒng)一異常處理機(jī)制
  • 沒有規(guī)范化的日志格式 - 日志格式混亂

但不可否認(rèn),他一定是當(dāng)前最快的。這就是戰(zhàn)術(shù)設(shè)計的特點(diǎn)之一,永遠(yuǎn)按當(dāng)前最快速交付的方案進(jìn)行推進(jìn),甚至很多組織鼓勵這種工作方式,為了使功能更快運(yùn)作,只注重短期收益而忽略長期價值。

戰(zhàn)術(shù)龍卷風(fēng)

Almost every software development organization has at least one developer who takes tactical programming to the extreme: a tactical tornado.

-- John Ousterhout 《A Philosophy of Software Design》

譯:幾乎每個軟件開發(fā)組織都有至少一個將戰(zhàn)術(shù)編程發(fā)揮到極致的開發(fā)人員:戰(zhàn)術(shù)龍卷風(fēng)。

將戰(zhàn)術(shù)編程發(fā)揮到極致的人,叫戰(zhàn)術(shù)龍卷風(fēng)。戰(zhàn)術(shù)龍卷風(fēng)以腐化系統(tǒng)為代價換取當(dāng)前最高效的解決方案(或許他自己并未覺得)。戰(zhàn)術(shù)龍卷風(fēng)也有如下幾個特點(diǎn):

  • 是一位多產(chǎn)的程序員,沒人比龍卷風(fēng)更快完成任務(wù)
  • 總能留下龍卷風(fēng)后毀滅的痕跡??留給后人去清理
  • 是真的很卷

一些組織甚至?xí)?zhàn)術(shù)龍卷風(fēng)視為英雄,為什么能干得又多又快?因為他將成本放到了未來。軟件工程最大的成本在于維護(hù),我們每一次代碼的改動,都應(yīng)該是對歷史代碼的一次整理,而非單一的功能堆積。龍卷風(fēng)能贏得現(xiàn)在,但終將失去未來,而這個失敗的未來或許需要全團(tuán)隊與他一起買單。

戰(zhàn)略編程

John教授提出與戰(zhàn)術(shù)編程相對的是戰(zhàn)略編程,戰(zhàn)略編程更注重長期價值,不滿足于功能work,致力于制作出色的設(shè)計,以滿足對未來擴(kuò)展的訴求(注意,不要過度)。戰(zhàn)略設(shè)計有如下4個特點(diǎn)

  • 工作代碼遠(yuǎn)遠(yuǎn)不夠
  • 引入不必要的復(fù)雜度不可接受
  • 不斷對系統(tǒng)設(shè)計進(jìn)行小幅改進(jìn)
  • 投資心態(tài)(每位工程師都需要對良好的設(shè)計進(jìn)行連續(xù)的少量投資 10~20%)

John Ousterhout教授在 A Philosophy of Software Design 書中提到了戰(zhàn)略設(shè)計與戰(zhàn)術(shù)設(shè)計的總成本投入。隨著時間的流逝,戰(zhàn)略設(shè)計可以有效控制軟件成本,但戰(zhàn)術(shù)設(shè)計會隨著時間的推移線性遞增。這與Martin Fowler在 Patterns of Enterprise Application Architecture 這本書中所提的關(guān)于數(shù)據(jù)驅(qū)動與領(lǐng)域驅(qū)動關(guān)于復(fù)雜度的治理是同樣的含義,要致力于長期的價值投資。

4.系統(tǒng)的困境與演進(jìn)

沒有系統(tǒng)是天然復(fù)雜的,為了快速完成任務(wù)不斷引入新的復(fù)雜度至系統(tǒng)逐漸腐化,無限增長與無限傳遞的復(fù)雜度讓軟件需求越來越難“快速完成”。當(dāng)有一天我們意識到系統(tǒng)的復(fù)雜性時再試圖通過戰(zhàn)略設(shè)計進(jìn)行軟件的迭代,你會發(fā)現(xiàn)舉步維艱,一處很小的修改需要投入大量的基建修復(fù),最終我們不得不向成本低頭,不斷再通過戰(zhàn)術(shù)設(shè)計無限的茍且。

A condition that is often incorrectly labeled software maintenance. To be more precise, it is maintenance when we correct errors; it is evolution when we respond to changing requirements; it is preservation when we continue to use extraordinary means to keep an ancient and decaying piece of software in operation. Unfortunately, reality suggests that an inordinate percent- age of software development resources are spent on software preservation.

-- Grady Booch 《Object-Oriented Analysis and Design with Applications》

譯:我們總是說我們需要“維護(hù)”這些老系統(tǒng)。而準(zhǔn)確的說,在軟件發(fā)展過程里,只有我們修正錯誤時,才是維護(hù);在我們應(yīng)對改變的需求時,這是演進(jìn);當(dāng)我們使用一些極端的手段來保持古老而陳腐的軟件繼續(xù)工作時,這是保護(hù)(茍且)。事實證明我們更多的時間是在應(yīng)對最后一種狀況。

如同Grady Booch在 Object-Oriented Analysis and Design with Applications 中所提到的觀點(diǎn),當(dāng)我們使用一些極端的手段來保持古老而陳腐的軟件繼續(xù)工作時,這確實是一種茍且。我們小心翼翼、集成測試、灰度發(fā)布、及時回滾等等,我們沒有在“維護(hù)”他們,而是以一種丑陋的方式讓這些丑陋的代碼繼續(xù)能夠成功茍且下去。當(dāng)代碼變成意大利面條時,將幾乎是不可能修復(fù),成本將成指數(shù)倍增長,并且似乎我們的系統(tǒng)已經(jīng)存在這樣的代碼,并且可能還在持續(xù)增加中。

六、架構(gòu)偽論

在架構(gòu)設(shè)計中,總有一些軟件工程師所堅信的詩和遠(yuǎn)方,但到不了的烏托邦不一定就是遙不可及的美好圣地,實則也可能是對系統(tǒng)無益甚至有害的架構(gòu)設(shè)計。這里列舉其中2條可能存在的架構(gòu)偽論。

1.好的代碼自解釋

Comments do not make up for bad code

-- Martin Fowler 《Clean Code》

譯:注釋不是對劣質(zhì)代碼的補(bǔ)救

Martin Fowler在 Clean Code 書中提到注釋不是對劣質(zhì)代碼的補(bǔ)救,以前我也一直堅信如果代碼足夠好是不需要注釋的。但實則這是一個偽命題,John教授這么評價它 ‘good code is self-documenting’ is a delicious myth。

/**
* 批量查詢客戶信息
*/
public List<CustomerVO> queryCustomerList(){
// 查詢參數(shù)準(zhǔn)備
UserInfo userInfo = context.getLoginContext().getUserInfo();
if(userInfo == null || StringUtils.isBlank(userInfo.getUserId())){
return Collections.emptyList();
}
LoginDTO loginDTO = userInfoConvertor.convert(userInfo);
// 查詢客戶信息
List<CustomerSearchVO> customerSearchVOList = customerRemoteQueryService.queryCustomerList(loginDTO);
Iterator<CustomerSearchVO> it = customerSearchVOList.iterator();
// 排除不合規(guī)客戶
while(it.hasNext()){
CustomerSearchVO customerSearchVO = it.next();
if(isInBlackList(customerSearchVO) || isLowQuality(customerSearchVO)){
it.remove();
}
}
// 補(bǔ)充客戶其他屬性信息
batchFillCustomerPositionInfo(customerSearchVOList);
batchFillCustomerAddressInfo(customerSearchVOList);
return customerSearchVOList;
}

這段代碼我們可以很輕松的在5秒內(nèi)看明白這個函數(shù)是做什么的,并且知道它內(nèi)部的一些業(yè)務(wù)規(guī)則。無限的私有方法封裝會讓代碼鏈路過深,無限類的拆解會造成更多網(wǎng)狀依賴,至少有3點(diǎn)內(nèi)容,讓我們絕不能拋棄注釋。

無法精準(zhǔn)命名

命名的含義是抽象實體隱藏細(xì)節(jié),我們不能在一個名字上賦予它全部的信息,而必要的注釋可以完美的進(jìn)行輔佐。

設(shè)計思想的闡述

代碼只能實現(xiàn)設(shè)計不能闡述設(shè)計,這也是為什么一些復(fù)雜的架構(gòu)設(shè)計我們需要文檔的支撐而非代碼的‘自解釋’,在文檔與代碼之間的空隙,由注釋來填補(bǔ)。

母語的力量

這點(diǎn)尤其適合我們中國人,有時并不是因為注釋少代碼多,所以我們下意識會首先看代碼。而是我們幾十年感受的文化,讓我們對中文與ABC具有完全不一樣的感觀。

2.永遠(yuǎn)追求最優(yōu)雅

雷布斯曾自夸自己寫的代碼像詩一樣優(yōu)雅,追求優(yōu)雅的代碼應(yīng)該是每個軟件工程師的心中的圣地。但有時存在一些不優(yōu)雅,存在一些‘看似不合理’并不代表就不對,反而有時在追求更優(yōu)雅的路上我們持續(xù)跑偏。

The goal of software architecture is to minimize the human resources required

to build and maintain the required system.

-- Robert C.Martin 《Clean Architecture》

譯:軟件架構(gòu)的終極目標(biāo)是,用最小的人力成本來滿足構(gòu)建和維護(hù)該系統(tǒng)的需求

Robert C.Martin在 Clean Architecture 一書中提到了架構(gòu)終極目標(biāo),用最小的人力成本來滿足構(gòu)建和維護(hù)該系統(tǒng)的需求。架構(gòu)始終是我們解決復(fù)雜度的一個工具,如果當(dāng)前系統(tǒng)并不復(fù)雜,我們不需要為了所謂的優(yōu)雅去過分改造與優(yōu)化它,持續(xù)將成本置在一個較低水位,就是軟件最好的解決辦法。

業(yè)務(wù)簡單的系統(tǒng)不應(yīng)用DDD架構(gòu),弱交互場景也無需進(jìn)行前后端分離,哪怕是鄧總設(shè)計師在規(guī)劃新中國的發(fā)展上,也是制定了一套‘中國特色社會主義’制度。不要盲從一些教條的觀念,選擇適合自己的,控制在可控制范圍內(nèi),既不過度也不缺失。畢竟沒有絕對的優(yōu)雅,甚至沒有絕對的正確。

七、寫在最后

很多人認(rèn)為做業(yè)務(wù)開發(fā)顯得沒那么有挑戰(zhàn)性,但其實正好相反。最難解決的bug是無法重現(xiàn)的bug,最難處理的問題域是不確定性的問題域。業(yè)務(wù)往往是最復(fù)雜的,面向不確定性設(shè)計才是最復(fù)雜的設(shè)計。軟件工程學(xué)科最難的事情是抽象,因為它沒有標(biāo)準(zhǔn)、沒有方法、甚至沒有對錯。如何在軟件固有的復(fù)雜性上找到一條既不過度也不缺失的路,是軟件工程師的終身課題,或許永遠(yuǎn)也無法達(dá)到,或許我們已經(jīng)在路上了。

參閱書籍

《A Philosophy of Software Design》《Object Oriented Analysis and Design with Applications》《Clean Code》《Clean Architecture》《Patterns of Enterprise Application Architecture》


責(zé)任編輯:武曉燕 來源: 阿里技術(shù)
相關(guān)推薦

2021-03-29 16:32:03

軟件代碼程序員

2020-08-10 09:07:00

數(shù)據(jù)庫IT技術(shù)

2019-02-28 08:44:19

內(nèi)網(wǎng)釘釘Web

2019-03-03 16:47:58

云計算公共云成本

2019-02-20 18:33:01

云計算公共云成本

2024-04-25 08:33:25

算法時間復(fù)雜度空間復(fù)雜度

2018-12-18 10:11:37

軟件復(fù)雜度軟件系統(tǒng)軟件開發(fā)

2021-01-05 10:41:42

算法時間空間

2024-05-20 09:04:29

時間復(fù)雜度代碼

2009-07-09 10:45:16

C#基本概念復(fù)雜度遞歸與接口

2020-09-08 15:40:58

算法快速排序堆排序

2022-02-21 23:08:50

Kubernetes集群容器

2015-10-13 09:43:43

復(fù)雜度核心

2020-12-30 09:20:27

代碼

2019-01-02 05:55:30

領(lǐng)域驅(qū)動軟件復(fù)雜度

2024-04-15 12:48:00

2020-08-24 08:15:29

軟件互聯(lián)網(wǎng)分布式

2019-12-24 09:46:00

Linux設(shè)置密碼

2022-08-16 09:04:23

代碼圈圈復(fù)雜度節(jié)點(diǎn)

2019-11-18 12:41:35

算法Python計算復(fù)雜性理論
點(diǎn)贊
收藏

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

欧美日本国产视频| 国产亚洲成aⅴ人片在线观看| 九九热精品在线| 人妻av一区二区| 日韩中文影院| 亚洲天堂av老司机| 国产一区二区不卡视频在线观看| 无码人妻丰满熟妇区bbbbxxxx| 91免费精品| 亚洲第一视频网站| 国产福利在线免费| 国产伦理精品| 亚洲欧美综合色| 久久99精品国产一区二区三区| 中文字幕日产av| 亚洲国产欧美国产综合一区| 最近2019年中文视频免费在线观看| 国产又黄又嫩又滑又白| 日韩另类视频| 亚洲国产精品综合小说图片区| 亚洲精品第一区二区三区| 国产成人无码www免费视频播放| 日韩在线一区二区| 97在线视频免费观看| 国产又粗又猛又爽又黄的视频四季 | 91精品入口| 欧美主播一区二区三区| 黄页网站在线观看视频| 91中文在线| 欧美激情综合五月色丁香| 国严精品久久久久久亚洲影视| 国产又粗又大又爽视频| 天堂蜜桃91精品| 韩国美女主播一区| wwwav国产| 国产国产精品| 在线观看久久久久久| 丰满大乳奶做爰ⅹxx视频| 综合激情五月婷婷| 欧美一区二区视频观看视频 | 久久婷婷一区二区| 五月天激情综合网| 最新的欧美黄色| 日本人亚洲人jjzzjjz| 久久99国产成人小视频| 日韩电影视频免费| 天堂www中文在线资源| 在线观看视频一区二区三区 | 三级毛片在线免费看| 粉嫩aⅴ一区二区三区四区| 91视频免费在线| 国产一区二区在线视频聊天| 蜜桃久久久久久| 国产精品久久视频| 中文字幕 日韩有码| 日本色综合中文字幕| 国产精品va在线| 中文字幕 欧美激情| 麻豆一区二区三区| 成人免费在线视频网站| 国产精品久久久久久69| 国产精品中文字幕日韩精品| 91视频免费网站| 亚洲国产福利视频| 成人免费高清在线观看| 国产日韩精品一区观看| 三级毛片在线免费看| 久久精品亚洲国产奇米99| 日本a级片久久久| 中文字幕日本在线| 亚洲免费视频中文字幕| 人人妻人人做人人爽| 蜜桃av在线播放| 91久久精品一区二区| 中文字幕国产传媒| 四虎地址8848精品| 精品日韩在线一区| 亚洲天堂网一区二区| 精品国产一区二区三区四区| www亚洲欧美| 久久免费公开视频| 毛片一区二区| 91啪国产在线| 性猛交xxxx| 国产精品久久精品日日| 成年在线观看视频| 三上悠亚国产精品一区二区三区| 欧美日韩黄视频| 美女露出粉嫩尿囗让男人桶| 精品在线99| 久久天堂电影网| 日韩久久久久久久久| 日本欧美在线观看| 官网99热精品| 国产51人人成人人人人爽色哟哟| 亚洲精品欧美激情| 哪个网站能看毛片| 精品国产一级| 亚洲性线免费观看视频成熟| 免费网站观看www在线观| 亚洲一区亚洲| 97碰碰视频| 成人一区二区不卡免费| 亚洲一卡二卡三卡四卡| 日本人视频jizz页码69| 欧美freesex8一10精品| 久久精品国产亚洲精品| 五月婷婷视频在线| 国产高清视频一区| 亚洲欧洲国产日韩精品| 超碰在线网站| 欧美精品少妇一区二区三区| 精品中文字幕在线播放| 91精品推荐| 国产精品大片wwwwww| 欧美熟妇乱码在线一区| 中文字幕日韩一区| 免费日韩中文字幕| 欧美日韩麻豆| 久久久久久久成人| 国产熟女一区二区丰满| 国产日韩精品一区二区三区在线| xxxx18hd亚洲hd捆绑| 日韩免费一级| 精品国模在线视频| 最近中文字幕免费观看| 91麻豆精东视频| www.av毛片| 日韩精品三级| 久久午夜a级毛片| 国产精品sm调教免费专区| 2024国产精品| 欧美 日韩 激情| 精品亚洲自拍| 性欧美xxxx| 亚洲福利在线观看视频| 一区二区三区在线视频观看58| 亚洲精品手机在线观看| 欧美手机在线| 国产精品69精品一区二区三区| 亚州男人的天堂| 欧美日韩亚洲成人| 污污免费在线观看| 激情91久久| 国产一区二区高清视频| 岛国av免费在线观看| 欧美mv日韩mv亚洲| 奇米影视第四色777| 成人动漫精品一区二区| 国产av人人夜夜澡人人爽麻豆| 97se亚洲国产一区二区三区| 欧美激情网友自拍| 日本免费一区视频| 精品久久久久久亚洲国产300| 中文字幕第3页| 国产日韩欧美三级| 日本中文不卡| 精品久久久网| 一二三四社区欧美黄| 亚洲色欲久久久综合网东京热| 99re8精品视频在线观看| 婷婷亚洲久悠悠色悠在线播放| 国产成人在线视频| 日本成人三级电影网站| 色偷偷男人天堂| 人妖一区二区三区| 狠狠色狠色综合曰曰| 不卡av免费在线| 麻豆系列在线观看| 99精品一区二区| 深夜福利成人| 青青草免费观看免费视频在线| 精品欧美久久| 奇米精品一区二区三区在线观看| 亚洲a成v人在线观看| 黄网址在线观看| 亚洲成人av中文字幕| caoporn国产| 国产精品全国免费观看高清| 男女啪啪的视频| av一级亚洲| 国产91色在线|| 日本电影全部在线观看网站视频 | 国产女主播福利| 一区二区在线观看av| 亚洲色图14p| 日韩一级免费| 日本一区二区三区视频免费看| 国产极品一区| 亚洲天堂第二页| 国产免费黄色片| 精品久久久久久久中文字幕| 林心如三级全黄裸体| 国产91丝袜在线观看| 成人在线看视频| 精品精品国产毛片在线看| 国产精品999999| 免费人成在线观看播放视频| 亚洲国产精品免费| 91精品国产乱码久久久久| 亚洲一本大道在线| 992在线观看| 99精品热视频| 亚洲精品国产久| 丝袜亚洲另类欧美综合| 国产一区二区三区小说| 日韩黄色大片网站| 久久久国产精品一区二区三区| 日韩精品一页| 日韩美女写真福利在线观看| 日韩专区av| 色先锋资源久久综合5566| 亚洲 欧美 激情 另类| 欧美一区日韩一区| 波多野结衣视频观看| 亚洲午夜国产一区99re久久| 国产又粗又猛又爽又黄的视频小说| www.欧美.com| 久久久久久国产精品日本| 日本视频一区二区三区| 欧美日韩二三区| 狠狠久久婷婷| 强开小嫩苞一区二区三区网站| 狠狠色狠狠色综合婷婷tag| 国产精品免费一区二区三区四区 | 日韩一区二区三区免费观看| 最近中文字幕免费在线观看| 狠狠色狠狠色综合日日五| 精品午夜福利在线观看| 亚洲精品国产视频| 美女福利视频网| 欧美激情一区二区三区全黄| 极品粉嫩小仙女高潮喷水久久| 成人污视频在线观看| 亚洲成人av免费观看| 久久99精品久久久久| 午夜国产一区二区三区| 久久婷婷亚洲| 免费日韩中文字幕| 久久亚洲视频| 日韩av播放器| 日本午夜一本久久久综合| 亚洲色图38p| 日韩成人dvd| 熟女少妇精品一区二区| 亚洲神马久久| 国产在线青青草| 欧美中文日韩| 一本久道中文无码字幕av| 亚洲国内精品| 成人在线免费在线观看| 性欧美xxxx大乳国产app| www国产精品内射老熟女| 制服诱惑一区二区| www.浪潮av.com| 久久久久久穴| 69久久久久久| 国产一区二区三区四区五区入口| 九一精品久久久| 国产乱码精品一品二品| 在线成人精品视频| caoporm超碰国产精品| jizz欧美性20| 中文av一区特黄| 日本一级片免费| 一区二区三区美女| www日韩精品| 在线视频一区二区免费| 亚洲字幕av一区二区三区四区| 欧美裸体bbwbbwbbw| 国产高清第一页| 亚洲国产天堂久久国产91| 男人的天堂在线视频| 中文字幕一精品亚洲无线一区 | 懂色av一区二区三区四区| 亚洲高清av在线| 国产在线一在线二| 蜜臀久久99精品久久久无需会员| 羞羞的视频在线看| 97精品久久久| 国内欧美日韩| 国产精品大全| 欧美另类69xxxxx| 色一情一乱一乱一区91| 国产欧美二区| 中文字幕国产高清| 91在线视频观看| 情侣偷拍对白清晰饥渴难耐| 亚洲国产精品嫩草影院| 国产免费www| 欧美va亚洲va香蕉在线 | 麻豆成人在线看| 中文字幕在线视频网站| 91久久久国产精品| 欧美天堂社区| 亚洲成人动漫在线| 嫩草成人www欧美| 在线观看欧美一区二区| 久久久久久综合| 午夜69成人做爰视频| 色婷婷国产精品综合在线观看| 国产精品爽爽久久久久久| 日韩精品在线观看网站| av在线免费观看网址| 日本午夜精品理论片a级appf发布| 精品中文字幕一区二区三区四区| 麻豆久久久av免费| 国内一区二区三区| 亚洲人视频在线| 久久香蕉国产线看观看99| 九九热国产精品视频| 欧美日韩在线播放三区| 四虎国产精品永远| 欧美日韩不卡合集视频| 色狠狠一区二区三区| 欧美大香线蕉线伊人久久| 欧美精品一级| 免费成人黄色大片| 久久精品亚洲麻豆av一区二区 | 免费污视频在线| 成人在线精品视频| 成人情趣视频网站| 欧美日韩第二页| www..com久久爱| 久热这里只有精品在线| 91精品国产综合久久精品 | 中文字幕一区不卡| 美女黄页在线观看| 亚洲区一区二区| 芒果视频成人app| 欧美成ee人免费视频| 亚洲精品女人| 午夜不卡久久精品无码免费| 一区二区三区精密机械公司| 国产富婆一级全黄大片| 久久电影一区二区| 深夜日韩欧美| 免费国产成人看片在线| 九色综合狠狠综合久久| 制服丨自拍丨欧美丨动漫丨| 91久久精品午夜一区二区| 免费在线国产| 日本久久久久久久久| 在线日本制服中文欧美| 国产xxxxx在线观看| 26uuu国产在线精品一区二区| 日韩人妻无码一区二区三区99| 精品国产青草久久久久福利| 久久免费电影| 精品蜜桃一区二区三区| 亚洲综合日本| 欧美 日韩 成人| 欧美日韩综合在线免费观看| 91欧美在线视频| 成人激情黄色网| 欧美午夜一区二区福利视频| 国产亚洲精品成人a| 午夜精品久久久久| 色在线免费视频| 国产精品99蜜臀久久不卡二区| 日韩欧美一区二区三区在线视频| 九九九九九九九九| 亚洲另类中文字| 欧美一级特黄aaaaaa| 欧洲成人性视频| 精品国产一区二区三区小蝌蚪| 五月天视频在线观看| 一区二区三区影院| 四虎影院在线域名免费观看| 国产精品96久久久久久又黄又硬| 999成人网| 女同性αv亚洲女同志| 粉嫩老牛aⅴ一区二区三区| 国产在线视频网站| 成人午夜在线观看| 亚洲精品少妇| 丰满的亚洲女人毛茸茸| 日韩欧美一级二级三级| 345成人影院| 婷婷视频在线播放| 成人av在线一区二区| 欧美超碰在线观看| 欧美成人一二三| 影视先锋久久| 免费不卡av网站| 日韩欧美国产激情| av在线官网| 欧美重口乱码一区二区| 国产一区三区三区| 中文字幕第四页| 欧美成年人在线观看| 国产不卡av一区二区| 在线播放黄色av| 在线免费观看成人短视频| 四虎影视国产在线视频| 美女精品国产| 国产成人在线看| 国产情侣呻吟对白高潮| 久久久爽爽爽美女图片| 久久精品99久久无色码中文字幕|