不,這不是上帝說的。
這也不是Jon Skeet / Martin Fowler / Jeff Atwood / Joel Spolsky(可以用你最喜歡的技術專家的替換這些名字)說的。
我們正在審查一些程式碼,並開始討論為什麼我們走捷徑,不遵循常識原則。雖然每個人在對待關於類應該如何基於功能上下文來構建的問題上都有自己的智慧,但仍然有一些基本原則值得我們在設計類的時候牢牢記住。
I.遵循單一職責原則
每個類都應該有一個並且只有一個引起它變化的原因。這不僅適用於類,方法也是如此。不知道你有沒有見到過那些長篇大論的冗餘的類和方法,當將它們寫到紙上的時候,簡直就是懶婆娘的裹腳布——又臭又長?好吧,我們要提出的觀點是不要這樣做。
該原則的要點就是每個類或方法都有一個存在的理由。如果類被命名為Loan,那麼它就不應該處理銀行帳戶的相關細節。如果方法被命名為GetLoanDetails,那麼它應該負責獲取貸款的詳細資訊!
II.遵循開放封閉原則
這一條使你能夠思考你的系統將如何適應未來的變化。它指出,系統應該允許新增新的功能,但對現有程式碼的更改要做到最少。因此,設計對於擴充套件應該是開放的,但對於修改應該是封閉的。在我們的例子中,開發人員做了這樣的事情:
public class PersonalLoan
{
public void Terminate() {
//Execute Termination related rules here and terminate a personal loan
}
}
public class AutoLoan
{
public void Terminate() {
//Execute Termination related rules here and terminate a personal loan
}
}
public class LoanProcessor
{
public void ProcessEarlyTermination(object loan) {
if ( loan is PersonalLoan )
{
//Personal Loan processing
}
else if (loan is AutoLoan) {
//Auto Loan Processing
}
}
}
複製程式碼
LoanProcessor的問題是,當有一種新型別的Loan,例如HomeLoan出現的時候,它將不得不改變。結構最好是這樣:
public abstract class Loan
{
public abstract void Terminate();
}
public class PersonalLoan: Loan
{
public override void Terminate() {
//Execute Termination related rules here and terminate a personal loan
}
}
public class AutoLoan: Loan
{
public override void Terminate() {
//Execute Termination related rules here and terminate a personal loan
}
}
public class LoanProcessor
{
public void ProcessEarlyTermination(Loan loan) {
loan.Terminate();
}
}
複製程式碼
這樣的話,如果新增了新型別的Loan,那麼LoanProcessor也不會受影響。
III.嘗試使用組合優於繼承
如果不能正確地遵循這一條原則,那麼可能會導致脆弱的類層次。這個原則真的很簡單,只需要問一個問題——如果我要看子類,那麼我能不能說“Child是Parent的一種型別?”或者,它更像“Child某種程度上是Parent的一種型別?“
始終對第一個問題使用繼承,因為它將允許使用Child無論Parent在哪裡。這也將允許你能夠實現另一個稱為Liskov替代原則的設計原則。並且在你想部分使用一個類的功能的時候使用組合。
IV.封裝資料和行為
大多數開發人員只做資料封裝,忘記封裝基於上下文而變化的程式碼。不但隱藏類的私有資料很重要,而且建立被良好封裝的作用於私有資料的方法也很重要。
V.類遵循鬆散耦合原則
這與封裝正確的行為是相輔相成的。如果行為被很好地封裝在類中,那麼就只能建立鬆散耦合的類。我們可以通過依賴於抽象而不是實現來做到鬆散耦合。
VI.使類高度內聚
我們不應該在不同的類之間散開資料和行為。應該努力使類不洩露/打破實現到其他類的細節。這意味著不允許類有程式碼,因為這樣超出了它存在的目的。當然,有一些設計範例,如CQRS,會希望你在不同的類中隔離某些型別的行為,但它們只用於分散式系統。
VII.編碼介面而不是實現
這促進了鬆散耦合原則,並使得我們能夠改變底層實現或引入新的實現,而不影響使用它們的類。
VIII.保持DRY(Don’t Repeat Yourself)
也是一個宣告不要在兩個不同的地方重複相同程式碼的設計原則。也就是說,特定功能或演算法應當,僅,在一個地方實現。如果重複實現的話,則會導致維護問題。與此相反的是WET原則——Write Everything Twice。
IX.最少知識原則,也叫做迪米特法則。
這個原則宣告物件不應該知道它協作物件的內部細節。它被著名地稱為——與朋友交流,不要和朋友的朋友交流。類應該只能呼叫它正在協作的類的公共資料成員。不應該被允許訪問由那些資料成員組成的類的行為或資料。如果不能正確遵守,則會導致緊密耦合,從而建立出更難改變的系統。
X.遵循好萊塢原則:Don’t Call Us, We’ll Call You
這能夠打破條件流邏輯的模型,並允許基於事件執行程式碼。這要麼通過事件回撥,要麼通過注入介面的實現來完成。依賴注入,控制反轉或觀察者設計模式都是這個原則的好例子。這個原則促進了類之間的鬆散耦合,並使得實現非常可維護。
最後,給大家推薦一個前端學習進階內推交流群685910553(前端資料分享),不管你在地球哪個方位, 不管你參加工作幾年都歡迎你的入駐!(群內會定期免費提供一些群主收藏的免費學習書籍資料以及整理好的面試題和答案文件!)如果您對這個文章有任何異議,那麼請在文章評論處寫上你的評論。
如果您覺得這個文章有意思,那麼請分享並轉發,或者也可以關注一下表示您對我們文章的認可與鼓勵。
願大家都能在程式設計這條路,越走越遠。