如何擺脫爛專案的糾纏

2022-04-09 04:10:57 字數 2671 閱讀 8553

有沒有這樣覺得,以前做過的,剛做完的,或者正在做的專案,簡直就是狗屎,不想去維護,不想去看以前寫的**?如果有,那麼我們可以繼續下面的內容。

分析一下原因,專案為什麼會爛,從純技術上去看無非有以下兩個問題:

專案架構爛 **質量差

下面我們各個擊破,分別說說我的一些愚見。專案架構往往是專案經理,架構師,團隊中技術較好程式設計師,或者呆公司較久程式設計師的事,由於對架構的理解不同,做事方式不同,專案的週期不同,技術選型不同,所以架構也就形形色色,但以我看來較鮮明的也就是較為守舊的資料庫先行,和時下流行的領域驅動。這兩者有明顯的區別,我覺得後者在架構上更有優勢,前者在開發周期上更有優勢,而且不需要很多前期設計,但是優雅程度遠不及後者,但在外包公司或者遇到很急的預算不多的專案往往會選擇前者。

資料庫先行架構的一般流程:

需求分析 設計資料庫 編寫或使用工具生成實體類(dto) 編寫邏輯

領域模型架構的一般流程:

需求分析 分析業務,整理領域物件,劃分物件之間關係(理出聚合根) 為領域物件寫行為

兩者共同點:都可以採用aop,物件導向,設計模式來提公升程式的可維護性,但後者物件導向的味道更濃,從架構上講有先天的優勢。

資料庫先行給專案帶來的問題

1. 由於依賴資料庫,團隊中多數人更喜歡寫sql,寫sql不是壞事,但是太多的sql,甚至邏輯都採用寫sql去處理,勢必造成可維護性降低,原因如下:

sql先天性決定,sql沒有物件導向的概念,這意味著,它的抽象層次較低,流程式的**很難做到高維護性,高封閉性,很多相同邏輯的**需要重複寫在不同的儲存過程裡面,雖然可以提煉到函式或者另外的儲存過程中,但那是個不容易的事。 既然很多邏輯寫到資料層面,那比如時間的處理,資料的轉換,驗證,錯誤的處理,很大程度也都依賴資料庫,很明顯,資料庫相對於物件導向的語言並不擅長。這樣做幾乎讓專案的可維護性降到最低。 缺少或薄弱的現代ide的很多編碼優勢,如智慧型提示,編譯期糾錯,這一點使可測試性大大降低,你甚至很難做單元測試。

當然優點也有,那就是易於發布和效能會略高一籌。 

2. 較好的方式,是把邏輯寫到**裡,資料庫只用來持久化資料,這裡又有兩種風格

使用orm,sql為框架生成,這種方式普遍,好處是有成熟的orm框架(如ef,nhibernate等)幫我們生成sql,我們省去了在**裡寫sql造成如,可維護性低,被sql注入的風險,且能享受**智慧型提示,編譯期糾錯等待遇。 寫儲存過程,這裡與上一點的不一樣,這種方式只是將crud操作寫成儲存過程,邏輯寫**裡,這種方式的優點是利於發布。缺點是要手動寫實體類和儲存過程,不過我們可以使用工具生成。

資料庫先行的優點

架構沒什麼複雜性,容易被團隊成員理解,容易交流 開發周期短,成本低

說說領域模型,它更像是一種思考問題的方式,它的出現就是為了為軟體開發提供乙個切實可行的指導思想,裡面包含太多思想,包括軟體開發原則,oo思想,解決問題的思路,如何易於測試,aop,等,感興趣的朋友可以去系統的學習一下,會有收穫的。

以上是架構上的問題,如果你有空間和時間建議你的考慮了順序為:

領域驅動 資料庫驅動,採用orm,邏輯寫程式

其他方式慎用。

回到開篇,再來說說如何寫出優雅的**,其實這是乙個累積的過程,當然前提是你在進步,進步是因為你意識到自己寫的**不夠優雅打算改進而採取學習和重構的結果。所以當你覺得**爛的時候,不要放棄,不要破罐子破摔,重構吧。既然要重構,就得找到需要重構的**,我能想到的爛**有:

1. 過長的方法

這裡是指,方法內容太長,發生這種情況,往往是封裝不好的結果,往往在乙個方法裡去實現乙個業務,而這個業務其實可是拆開到不同的物件中去,也就是這個操作不夠原子性,舉個例子,人喝可樂這個需求,業務流程應該是這樣:給人一瓶可樂,人需要開啟瓶子然後喝到不渴為止。

偽**如下:

public class person

var needcapactity = xx+yy-zz; //

while(cola.capacity <=needcapactity )

} }當然這段**並不長,只是為了說明方式,看得出來,這裡的問題有,驗證邏輯,獲取需要喝的容量,開蓋的方式都寫到裡面。

2. 硬編碼的字串和數字

if(age>50)

if(city.tolower()=="shengzhen")3. 職責不分明的類

4. 重複的**

其實提高**的重用,有幾個途徑:

繼承 工具方法 使用委託

前兩點都很容易理解,說一下這一點,舉個datacontext事務的例子。

using(var context = new datacontext())

); context.user.add(new user);

context.commit();

}catch

}以上**很常見吧,是不是每個使用事務地方都需要這麼寫,其實這個時候我們可以利用委託來實現。

public class dbinvoker

catch

} }}

以後用到事務的地方這樣呼叫就行了。

dbinvoker.transaction(context=>);

context.user.add(new user);

});是不是方便了許多?

5. 意義不準確的命名

6. ui與邏輯隔離差

這個最典型的我覺得就是比如在做web時,用mvc框架,卻在後端網前段輸出js的引用,或者長篇js,客戶端的東西了。

我就不一一舉例子了,最後說一句,優秀的開源專案要多看,感謝你的閱讀。

如何避免軟體專案的失敗

軟體開發中遇到的問題。symptoms of software development problems 以上問題的根本原因 root causes of software development problems 成功的實踐經驗 best practice best practices 是一系列商...

PyCharm如何匯入python專案的方法

進入pycharm後,點選file open,然後在彈窗中選擇需要匯入專案的資料夾 開啟了python專案後,需要配置該專案對應的python才可以正常執行 配置步驟 file settings 在設定彈窗中程式設計客棧選擇proj interpreter,然後點選add 在彈程式設計客棧窗中,選擇...

如何執行SpringBoot專案的方法

最近在ecplise上面寫了乙個簡單的spring boot的測試專案,sprintifmaphkg boot裡面是有主函式的 我們知道的是在ecplise上面找到這個主函式然後run as j a application 就可以了 但是總不能一直不脫離ecplise,總要出來自己單練的 第一步 我...