應該有且有一個緣由引發類的變動。架構
注意:
單一職責原則提出了一個編寫程序的標準,用」職責」或」變化緣由」來衡量接口或類設計得是否優良,可是」職責」和」變化緣由」都是不可度量得,因項目而異,因黃金而異。框架
對於單一職責原則,以我實際開發爲例,在公司開發項目,基本上沿用得開發模式就是MVC,模型-視圖-控制器,每一個職責不同。而後再往大的範圍來講,分層,好比數據訪問層、業務邏輯層、視圖表現層(其中該層就是MVC的應用)。
數據訪問層,一般編寫的就是一些基礎的CRUD,而業務邏輯層就是數據訪問層裏的CRUD一同用於處理某項業務。jsp
還有就是單一職責的一個體現就是一個函數辦一件事情,比方說業務邏輯層中修改密碼(設計db操做修改用戶信息),最好是修改密碼是一個方法,修改用戶基本信息(例如暱稱、性別、職位、籍貫等)是另一個方法。不一樣的方法(不一樣的函數)辦的事情不同,我以爲這樣也是單一職責的一個最好實踐。記得剛工做第一年的時候,寫代碼基本上數據訪問層就和業務邏輯層是同樣的,這樣的寫法致使的後果是,若是是少許的五到六個類還好,但若是數十個的話或成百上千個這樣寫的話,後果將會很是嚴重,直接會致使維護成本的上升,可擴展性差、可維護性差等。函數
最後概括一點,單一職責若是是以本身平時寫寫Demo玩玩而言實現起來並不困難。可是對於公司而言就不同了,拿我曾經接手的一個項目來講,該項目採用jfinal框架,而後前任架構師對其又再度修改封裝了不少東西,能夠稱之爲擴展。當我接手這個項目的時候,初看項目結構,捋了下,大體能根據包名看出功能分層,但當我深刻閱讀的時候,發現太多的拼接sql,並且業務邏輯層和數據訪問層並未分層明確,就像咱們通常開發喜歡分爲視圖、業務、數據這樣的分層,而這個項目基本上就是視圖(一種是返回jsp,另一種做爲路由返回JSON數據),業務實現(基本上就是寫業務邏輯的),還有較多的dto、request、response等包名下的衆多類。spa
一般我所認爲的最佳實踐就是:
1.分層(表現層-業務邏輯層-數據訪問層,每層作的事情不同);
2.一個函數只辦一件事情(也許你會發現你可能會編寫比較多的函數,例如用戶修改密碼,通常能夠修改用戶信息就能實現,可是通常建議分爲兩個,由於這樣一來當數據表結構發生變化,例如新增或修改字段,會下降不少影響,因此不要爲了偷懶就用一個函數辦兩件或多件事情);設計
對於單一職責原則,接口必定要作到單一職責,類的設計儘可能作到只有一個緣由引發變化。對象
繼承的優勢:繼承
繼承的缺點:接口
那麼什麼是里氏替換原則呢?
全部引用基類的地方必須能透明地使用其子類的對象。
通俗的來講:只要父類能出現的地方子類就能夠出現,並且替換爲子類也不會產生任何錯誤或異常,使用者可能根本就不須要知道是父類仍是子類。可是,反過來就不行了,有子類出現的地方,父類未必適應。
里氏替換原則爲良好的繼承定義了一個規範,一句簡單的定義包含4層含義。
注意:
a.在類中調用其餘類時務必要使用父類或接口,若是不能使用父類或接口,則說明類的設計已經違背了LSP原則;
b.若是子類不能完整地實現父類的方法,或者父類的某些方法在子類中已經發生」畸變」,則建議斷開父子繼承關係,採用依賴、彙集、組合等關係代替繼承。
子類能夠有本身的行爲和外觀,也就是方法與屬性,那這裏爲何要再提呢?
是由於里氏替換原則能夠正着用,可是不能反着用。在子類出現的地方,父類未必能勝任。
方法中的輸入參數稱爲前置條件,這是什麼意思?
WebService有一個」契約優先」原則,也就是先定義出WSDL接口,制定好雙方的開發協議,而後再各自實現。里氏替換原則也要求制定一個契約,就是父類或接口,這種設計方法也叫作契約設計,與里氏替換原則有着殊途同歸之妙。契約制定了,也就同時制定了前置條件和後置條件,前置條件就是你要讓我執行,就必須知足個人條件;後置條件就是我執行完了須要反饋,標準是什麼。
這是什麼意思呢?
父類的一個方法的返回值是一個類型T,子類的相同方法(重載或覆寫)的返回值爲S,那麼里氏替換原則就要求S必須小於等於T,也就是說,要麼S和T是同一個類型,要麼S是T的子類,爲何呢?
分兩種狀況:
若是是覆寫,父類和子類的同名方法的輸入參數是相同的,兩個方法的範圍值小於等於T,這是覆寫的要求,這纔是重中之重,子類覆寫父類的方法,天經地義。
若是是重載,則要求方法的輸入參數類型或數量不相同,在里氏替換原則要求下,就是子類的輸入參數寬於或等於父類的輸入參數,也就是說你寫的這個方法是不會被調用的,參考上面講的前置條件。
採用里氏替換原則的目的就是加強程序的健壯性,版本升級時也能夠保持很是好的兼容性。即便增長子類,原有的子類還能夠繼續運行。在實際項目中,每一個子類對應不一樣的業務含義,使用父類做爲參數,傳遞不一樣的業務含義,使用父類做爲參數,傳遞不一樣的子類完成不一樣的業務邏輯。
在項目中,採用里氏替換原則時,儘可能避免子類的」個性」,一旦子類有」個性」,這個子類和父類之間的關係就很難調和了,把子類當作父類使用,子類的」個性」被抹殺;把子類單獨做爲一個業務來使用,則會讓代碼間的耦合關係變得撲朔迷離,缺少類替換的標準。