面向對象設計的 10 條戒律

不,這不是上帝說的。前端

這也不是Jon Skeet / Martin Fowler / Jeff Atwood / Joel Spolsky(能夠用你最喜歡的技術專家的替換這些名字)說的。面試

咱們正在審查一些代碼,並開始討論爲何咱們走捷徑,不遵循常識原則。雖然每一個人在對待關於類應該如何基於功能上下文來構建的問題上都有本身的智慧,但仍然有一些基本原則值得咱們在設計類的時候緊緊記住。算法

image
10-commandments-of-ood

I.遵循單一職責原則

每一個類都應該有一個而且只有一個引發它變化的緣由。這不只適用於類,方法也是如此。不知道你有沒有見到過那些長篇大論的冗餘的類和方法,當將它們寫到紙上的時候,簡直就是懶婆娘的裹腳布——又臭又長?好吧,咱們要提出的觀點是不要這樣作。編程

該原則的要點就是每一個類或方法都有一個存在的理由。若是類被命名爲Loan,那麼它就不該該處理銀行賬戶的相關細節。若是方法被命名爲GetLoanDetails,那麼它應該負責獲取貸款的詳細信息!設計模式

II.遵循開放封閉原則

這一條使你可以思考你的系統將如何適應將來的變化。它指出,系統應該容許添加新的功能,但對現有代碼的更改要作到最少。所以,設計對於擴展應該是開放的,但對於修改應該是封閉的。在咱們的例子中,開發人員作了這樣的事情:bash

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也不會受影響。ide

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前端資料分享),無論你在地球哪一個方位, 無論你參加工做幾年都歡迎你的入駐!(羣內會按期免費提供一些羣主收藏的免費學習書籍資料以及整理好的面試題和答案文檔!)

若是您對這個文章有任何異議,那麼請在文章評論處寫上你的評論。

若是您以爲這個文章有意思,那麼請分享並轉發,或者也能夠關注一下表示您對咱們文章的承認與鼓勵。

願你們都能在編程這條路,越走越遠。

相關文章
相關標籤/搜索