|
關注+星標公眾號,不錯過精彩內容來源 | qryc
寫代碼這件事,有經驗的老司機都比較“煩惱”,直接寫吧,能快速寫完代碼,但會有一堆bug讓你加不完的班;慢慢整理業(yè)務邏輯、理清思路再寫吧,老板天天催進度。。。
今天就來分享一下關于業(yè)務邏輯與代碼的這些事兒。業(yè)務邏輯與代碼
1.代碼是需求邏輯的一種展現(xiàn)形式需求文檔是業(yè)務邏輯的一種展現(xiàn)形式,而代碼不過是業(yè)務邏輯的另一種表現(xiàn)形式;
如果邏輯本身有問題,那么它的各種展示形式自然也是錯的,所以寫代碼前應該先思考清楚業(yè)務邏輯。
2.Review代碼很多時候是邏輯問題在Review代碼經驗中發(fā)現(xiàn):混亂的代碼并不僅僅是代碼編寫技藝問題,很多時候是因為邏輯沒有梳理清楚。邏輯混亂,自然代碼也混亂。梳理清楚業(yè)務邏輯,就為代碼打下了良好的基礎。
當然業(yè)務邏輯梳理清楚后,業(yè)務邏輯到代碼的映射依然有可能出問題,這是編程技藝要解決的問題。
下面通過一個簡單的例子來演示這個過程。
業(yè)務需求示例
我們要做一件事情doSomething:第一步先做A,A過程要先執(zhí)行a1,然后執(zhí)行a2,然后執(zhí)行a3這三個子過程。第二步再做B,B過程需要執(zhí)行b1,然后b2這兩個子過程。
這個示例邏輯的圖形表述如下:是一個樹,包含樹的根,枝干,和葉子。
5iobmbknyg164079703719.jpg (75.52 KB, 下載次數(shù): 1)
下載附件
保存到相冊
5iobmbknyg164079703719.jpg
2024-10-12 08:44 上傳
例子是有通用性的,現(xiàn)實世界的任何事情或業(yè)務都可以用類似的樹形結構來表述。
正確的代碼實現(xiàn)
1.和邏輯樹映射的代碼樹正確的代碼結構應該是和邏輯映射的,代碼結構如下:
540oiulbcc264079703819.jpg (62.79 KB, 下載次數(shù): 0)
下載附件
保存到相冊
540oiulbcc264079703819.jpg
2024-10-12 08:44 上傳
我們真實寫代碼的時候,一般并不會直接寫出如上結構,而是會先寫出「2.代碼塊+注釋」的結構來。
2.代碼塊+合理注釋如下代碼通過代碼塊來映射邏輯,上面圖中的子函數(shù)對應代碼中的注釋。void doSomething(){ //A a1邏輯偽代碼.....;//a1 a2邏輯偽代碼.....;//a2 a3邏輯偽代碼.....;//a3
//B b1邏輯偽代碼;//b1 b2邏輯偽代碼;//b2}
3.抽取小函數(shù)可以再上面的基礎上更優(yōu)秀些,對代碼塊進行抽取小函數(shù),更符合業(yè)務描述(更符合業(yè)務的樹形結構)void doSomething(){ doA(); doB();}
void doA(){ a1邏輯偽代碼.....; a2邏輯偽代碼.....; a3邏輯偽代碼.....;}
void doB(){ b1邏輯偽代碼; b2邏輯偽代碼;}
當然你也可以繼續(xù)對a1,a2,a3,b1,b2等小邏輯映射為小函數(shù),以上提到幾種寫法都是正確的,關于小函數(shù)是否抽取,后續(xù)單獨在《代碼長度與母語的關系》中討論。下面我們來看看不正確的寫法。
不正確的代碼實現(xiàn)
當你看到下面的不正確的寫法的時候,你也許會覺得不可思議,真的會寫出這樣的代碼?
現(xiàn)實是:項目中我見到很多更糟糕的代碼,會把下面提到的問題,以及其他編程技藝的問題排列組合出現(xiàn)。
第一種問題:不對等第一種常見的問題不太嚴重,只對部分邏輯進行了抽取,造成函數(shù)中執(zhí)行不對等;比如只對b()邏輯進行了抽取,但對等的a()邏輯并未抽;
rmzrv0npwlh64079703919.jpg (57.86 KB, 下載次數(shù): 0)
下載附件
保存到相冊
rmzrv0npwlh64079703919.jpg
2024-10-12 08:44 上傳
void doSomething(){ a1邏輯偽代碼.....; a2邏輯偽代碼.....; a3邏輯偽代碼.....; doB();}
void doB(){ b1邏輯偽代碼; b2邏輯偽代碼;}
改進辦法參考上面第3部分正確的寫法,至少可以在doB();之前加空行,并對a1,a2,a3加個注釋,也會易讀很多(當然這是一種妥協(xié)寫法)。void doSomething(){ //a邏輯 a1邏輯偽代碼.....; a2邏輯偽代碼.....; a3邏輯偽代碼.....;
//b邏輯 doB();}
void doB(){ b1邏輯偽代碼; b2邏輯偽代碼;}
第二種問題:部分抽取第二種是對整體的部分邏輯進行了抽取,這種方法很難命名,會給個詞不達意的名字,或使用整體的名字,這個就相對嚴重了,已經影響到了代碼閱讀和理解。
比如電腦是一個整體,可以命名是電腦;如果只給你一部分(CPU,主板,顯卡)怎么命名讓人能明白?電腦部分零件?但電腦部分零件并不能讓人明白,因為它不是一個邏輯主體。CPU是一個邏輯主體,封裝了運算。
如下圖,只對a1,a2進行了抽取,然后名字依然稱為a,看到代碼會很疑惑,a3明顯也屬于a。
oidvge5pxgj64079704019.jpg (63.05 KB, 下載次數(shù): 1)
下載附件
保存到相冊
oidvge5pxgj64079704019.jpg
2024-10-12 08:44 上傳
void doSomething(){ doA(); a3邏輯偽代碼.....; doB();}
void doA(){ a1邏輯偽代碼.....; a2邏輯偽代碼.....;}
void doB(){ b1邏輯偽代碼; b2邏輯偽代碼;}
第三種問題:抽取錯誤第三種是最嚴重的問題,抽取錯誤,和邏輯不匹配。
如下:把A的部分邏輯和B的部分邏輯一起抽取。
如果在這個基礎上再對抽取的部分起個晦澀的名字(其實這種抽取也起不到好名字),然后應用一些設計模式來把代碼更分散(缺點隱藏起來),就成功的完成了只有自己可以看懂的代碼(可能表面看起來還很高大上)。
xxwnt3s0aai64079704120.jpg (58.24 KB, 下載次數(shù): 0)
下載附件
保存到相冊
xxwnt3s0aai64079704120.jpg
2024-10-12 08:44 上傳
由此得出結論,先別想著抽取小函數(shù)或應用設計模式。先能平鋪直敘的寫出符合邏輯的代碼吧。
小函數(shù)抽取和設計模式不一定能解決問題,也能隱藏問題。
很多難以讀懂的代碼都是受《重構》和《設計模式》的包裝,質量差的代碼不可怕,如果再抽取和包裝,可以想想是多恐怖。
補丁和模式思考
補丁代碼思考,代碼的腐爛很多人看到這里,會覺得自己絕對不會寫出這么爛的代碼;確實一開始也許不會,但伴隨新需求,不同人不斷打補。榱瞬挥绊懢上,老代碼不讓動),最后就會演進未這幾個問題綜合展現(xiàn)的代碼。閱讀這樣的代碼不看到最底層代碼,根本不知道代碼在做什么,因為函數(shù)名已經不可信。
不要急于使用設計模式,寫好基礎代碼寫出一個好的基礎代碼的過程:先梳理清楚邏輯樹(樹形結構,同層對等),然后做到代碼符合邏輯樹(代碼樹自然也符合樹形結構,同層的函數(shù)對等)。
打好基礎后,可以再針對基礎代碼的痛點,應用復雜手段(比如設計模式)來解決,關于函數(shù)抽取和函數(shù)長度,后續(xù)單獨文章討論。參考來源:https://zhuanlan.zhihu.com/p/435871448聲明:本文素材來源網(wǎng)絡,版權歸原作者所有。如涉及作品版權問題,請與我聯(lián)系刪除。
------------ END ------------
kgqwnw4rfrs64079704220.gif (71.87 KB, 下載次數(shù): 0)
下載附件
保存到相冊
kgqwnw4rfrs64079704220.gif
2024-10-12 08:44 上傳
●專欄《嵌入式工具》
●專欄《嵌入式開發(fā)》
●專欄《Keil教程》
●嵌入式專欄精選教程
關注公眾號回復“加群”按規(guī)則加入技術交流群,回復“1024”查看更多內容。
點擊“閱讀原文”查看更多分享。 |
|