寫了這麼多年程式碼,依舊做不好一個專案
做好一個專案是人力、產品、業務、技術、運營的結合,可能還疊加一點時機的因素,就我們碼農而言,工作就是搬磚,實現產品, 給業務提供支撐。
“給祖傳程式碼加 BUG 修 BUG”,“拿起鍵盤一把梭”這些戲謔程式設計師的話,聽多了真的會讓程式設計師麻木,彷彿大家都是這麼幹的。
從業多年,堆過 shi 山,接手過祖傳程式碼, 已經不能沉下氣去檢視、除錯 shi 山程式碼, 說實話,很累。
本人一直推崇寫流暢、自然、可自解釋的程式碼,讓優雅成為一種習慣, 給自己留個念想、給後人留個好評。
溫故而知新,聊一聊現代程式設計幾大常見的程式設計原則
普世原則 | |
---|---|
KISS (Keep It Simple Stupid) | 保持系統結構簡單可信賴 |
YAGNI (you aren't gonna need it) | 當前確實需要,再去做 |
Do The Simplest Things That Could Possibly Work | 思考最簡單可行的辦法 |
Separation of Concerns | 關注點分離 |
Keep Things DRY | 保持程式碼結構清爽 Don't repeat yourself |
Code For The Maintainer | 站在維護者角度寫程式碼 |
Avoid Premature Optimization | 避擴音前優化 |
Boy-Scout Rule | 清掃戰場:清理口水話註釋、無效程式碼 |
模組(類)間 | |
---|---|
Minimise Coupling | 低耦合 |
Law of Demeter | Don't talk to strangers,物件方法只接觸該接觸的物件、欄位、入參 |
Composition Over Inheritance | 組合而不是繼承 |
Orthogonality | 正相關,概念上不相關的事物不應在系統中強行相關 |
Robustness Principle | 程式碼健壯性 |
Inversion of Control | 控制反轉 |
模組(類) | |
---|---|
Maximise Cohesion | 高內聚 |
Likov Substitution Principle | 里斯替代原則:將程式中物件替換到子型別例項,不會報錯。 |
Open/Closed Principle | 設計的實體對擴充套件開放,對修改關閉 |
Single Responsiblity Principle | 單一責任原則 |
Hide Implementation Details | 隱藏實施細節 |
Curly's Law | 柯里定律:為確定目標編寫特定程式碼 |
Encapsulate What Changes | 封裝變化 |
Interface Segregation Principle | 介面隔離原則 |
Command Query Separation | 命令查詢分離 |
KISS
大多數系統保持簡單,會執行的很好。
- 更少的程式碼消耗更好的時間,產生更少的 bug,並且容易修改
- 複雜業務都是由簡單程式碼堆砌而成
- 完美並不是“沒有什麼東西可以再加”,而是“沒有什麼東西可以被去掉”
YAGNI
YAGNI 代表“you aren't gonna need it.”,不要自以為是的提前實現某些邊角,直到真正需要的時候,再來做。
- 提前做明天才需要做的工作,意味著當前迭代中需要花費更多精力
- 導致程式碼膨脹,軟體變得臃腫且複雜
Separation of Concerns
關注點分離是一種將計算機程式分為不同部分的設計原則,這樣每個部分都可以解決一個單獨的關注點。例如應用程式的業務邏輯是一個問題,而使用者介面是另外一個問題,更改使用者介面不應要求更改業務邏輯,反之亦然。
- 簡化應用程式的開發和維護
- 如果關注點分離得很好,則各個部分可以重複使用,也可以獨立開發和更新。
Interface Segregation Principle
介面隔離,將胖介面修改為多個小介面,呼叫介面的程式碼應該比實現介面的程式碼更依賴於介面。
why:
如果一個類實現了胖介面的所有方法(部分方法在某次呼叫時並不需要),那麼在該次呼叫時我們就會發現此時出現了(部分並不需要的方法),而並沒有機制告訴我們我們現在不應該使用這部分方法。
how: 避免胖介面,類永遠不必實現違反單一職責原則的介面。可以根據實際多職責劃分為多介面,類實現多介面後, 在呼叫時以特定介面指代物件,這樣這個物件只能體現特定介面的方法,以此體現介面隔離。
public interface IA
{
void getA();
}
interface IB
{
void getB();
}
public class Test : IA, IB
{
public string Field { get; set; }
public void getA()
{
throw new NotImplementedException();
}
public void getB()
{
throw new NotImplementedException();
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
IA a = new Test();
a.getA(); // 在這個呼叫處只能看到介面IA的方法, 介面隔離
}
}
Command Query Separation
命令查詢分離: 操作方法就只寫操作邏輯,查詢方法就只寫查詢邏輯,並以明顯的方法名區分自己的動作。
有了這個原則,程式設計師可以更加自信地進行編碼:由於查詢方法不會改變狀態,因此可以在任何地方以任何順序使用,使用操作方法時,也心中有數。
End
懂得這麼多道理,卻依舊過不好這一生。前人總結的程式設計原則和方法論需要在實踐中感悟,束之高閣,則始終不能體會程式設計的魅力和快感