1. 程式人生 > >第一章 單一職責原則 --(抄書)

第一章 單一職責原則 --(抄書)

這是本人閱讀秦小波老師的《設計模式之禪》第二版抄寫的,有很多省略,不適合直接閱讀,需要閱讀請出門左轉淘寶,右轉京東,支援秦老師(侵權請聯絡刪除)

第一章 單一職責原則

1.1我是“牛”類,我可以擔任多職嗎

單一職責原則的英文名稱是Single Responsibility Principle,簡稱SRP。這個設計原則備受爭議,只要你想和別人職責、慪氣或者吵架,這個原則是屢試不爽的。如果你是老大,看到一個介面或者類是這樣或那樣設計的,你就問一句:“你設計的類符合SRP原則嗎?”保準對方立馬會“萎縮掉”,而且還一臉崇拜地看著你,心想:“老大確實英明”。這個原則存在的爭議之處在哪裡呢?就是對職責的定義,什麼是類的職責,以及怎樣劃分類的職責。我們先舉個例子來說明什麼是單一職責原則。

只要做過專案,肯定要接觸到使用者、機構、角色管理這些模組,基本上使用的都是RBAC模型(Role-Based Access Control,基於角色的訪問控制,通過分配和取消角色來完成使用者許可權的授予和取消,使動作主體(使用者)與資源的行為(許可權)分離),確實是一個很好的解決辦法,我們這裡要講的是使用者管理、修改使用者資訊、增加機構(一個人屬於多個機構)、增加角色等,使用者有個這麼多的資訊和行為要維護我們就把這些寫到一個介面中,都是使用者管理類嘛,我們先來看看它的類圖

太easy的類圖了,我相信,即使是一個初級程式設計師也可以看出這個藉口設計的有問題,使用者的屬性和使用者的行為沒有分開,這是一個非常嚴重的錯誤!這個藉口確實設計的一團糟,應該把使用者的資訊抽取成一個BO(Business Object,業務物件),把行為抽取成一個Biz(Business Logic,業務邏輯),按照這個思路對類圖進行修正

重新拆分這兩個介面,IUserBO負責使用者的屬性,簡單地說,IUserBO的職責就是收集和反饋使用者的屬性資訊;IUserBiz負責使用者的行為,完成使用者資訊的維護和變更。各位可能要說了,這個與我實際工作中用到的User 類還是有差別的呀!彆著急,我們先看一看拆成兩個介面怎麼使用。OK,我們現在是面向介面程式設計所以長生了這個UserInfo物件之後,當然可以把它當IUserBO介面使用。也可以當成IUserBiz介面使用,這要看你在什麼地方使用了。要獲得使用者資訊,就當是IUserBO的實現類;要是希望維護使用者的資訊,就把它當做IUserBiz的實現類就成了,如下面程式碼

//new是在記憶體中建立了一個UserInfo物件,使用時應用為一個其他
IUserBiz  userInfo = new UserInfo();
//我要賦值了,我就認為它是一個純粹的BO 
IUserBO userBO = (IUserBO)userInfo;
userBO.setPassword("abc");
 //我要執行動作了,我就認為是一個業務邏輯類 
IUserBiz userBiz= (IUserBiz)userInfo; 
userBiz.deleteUser();

確實可以如此,問題也解決了,但是我們來分析一下剛才的動作,為什麼把一個介面拆分成兩個呢?其實,在實際的使用中,我們更傾向於使用兩個不同的類或介面:一個IUserBO,一個事IUserBiz,類圖

以上我們把一個介面拆分成兩個介面的動作,就是依賴了單一職責原則,那什麼是單一職責原則呢?單一職責原則的定義時:應該有且僅有一個原因引起累的變更。

1.2絕殺技,打破你的傳統思維

解釋到這裡,估計你已經不屑了,“切!這麼簡單的東西還要講?!”好我們講點複雜的。SRP的原話解釋是:

There should never be more than one reason for aclass to change.

這句話初中生都能看懂,不多說,但是看懂是一碼事,實施就是另外一碼事了。上面的例子很好理解,在實際專案中大家已經這麼做了,那我們再來看看下面這個例子是否好理解。電話這玩意兒,是現代人都離不開,電話通話的時候有4個過程發生:撥號、通話、迴應、掛機,那我們寫一個介面,其類圖

來我們看一下這個過程的程式碼