《設計模式》雜記之單一職責原則

《設計模式》雜記之單一職責原則

2011-04-13 23:48 by 王祖康, 1615 閱讀, 8 評論, 收藏, 編輯

最近買了本設計模式的書,名字叫《設計模式之禪》。這是我第一本設計模式的書,看了幾章了感覺自己受益匪淺,所以想就把自己感覺到比較有意思的設計模式知識分享給大家。

首先說一下我們程序員爲什麼要學習設計模式把!下面是引用書上的原話:

你是程序員,沒有問題,通過學習設計模式能夠讓你寫出更加高效,優雅的代碼;

你是架構師,那更好,設計模式可讓你設計出健壯,穩定,高效的系統,並且自動地預防未來業務變化可能對系統帶來的影響;

你是項目經理,也OK,設計模式可以讓你的工期大大縮短,讓你的項目團隊隊員快速地理解你的意圖,最終的成果就是優質的項目:高可靠性,高穩定性,高效率和低維護成本。

那麼我們看完這幾行話後,是不是有一種很想學習設計模式的感覺呢?反正我看完這幾行話後特別想把書讀完啊!呵呵~~~

好了,額不再廢話啦!開始切入正題吧!

設計模式分爲6大設計原則和23中設計模式。6大設計原則分別是:單一職責原則;里氏替換原則;依賴倒置原則;接口隔離原則;迪米特法則;開閉原則。23種設計模式分別是:單例模式;工廠方法模式;抽象工廠模式;模板方法模式;建造者模式;原型模式;中介者模式;命令模式;責任鏈模式;裝飾模式;策略模式;適配器模式;迭代器模式;組合模式;觀察者模式;門面模式;備忘錄模式;訪問者模式;狀態模式;解釋器模式;享元模式;橋樑模式。

這篇博文,我想主要介紹一下6大設計原則中的單一職責原則。

單一職責原則的英文名稱是Single Responsibility Principle,簡稱SRP。這個設計原則備受爭議,那麼爭議之處在哪裏呢?就是對職責的定義,什麼是類的職責,以及怎麼劃分類的職責。

RBAC模型(Role-Based Access Control),基於角色的訪問控制,通過分配和取消角色來完成用戶權限的授予和取消,使動作主體(用戶)與資源的行爲(權限)分離。下面我們來看一個類圖:

 

通過這個接口的設計,我們可以發現有一些問題,因爲用戶的屬性和用戶的行爲沒有分開。我們應該把用戶的信息抽取成一個BO(Bussness Object,業務對象),把行爲抽取成一個Biz(Business Logiz,業務邏輯),那麼我們就可以對這個類圖進行修改:

 

我們重新拆分成兩個接口,IUserBO負責收集和反饋用戶的屬性信息,IUserBiz負責用戶的行爲,完成用戶信息的維護和變更。

分清職責後的代碼就可以如下:

IUserBiz userInfo = new UserInfo();

    //實現業務對象

    IUserBO userBO = (IUserBO)userInfo;

    userBO.setPassword("wzk");

    //實現業務邏輯

    IUserBiz userBiz = (IUserBiz)userInfo;

    userBiz.deleteUser();

上面我把一個接口分成兩個接口的動作。就是依賴了單一職責原則,所以單一職責我就可以理解爲:應該有且僅有一個原因引起類的變更。

下面我們還是通過一個電話通話的例子來進一步說明單一職責原則,大家都知道我們在通電話的時候會有以下過程發生:撥號,通話,迴應,掛機。這個接口類圖如下:

 

這樣我們的代碼就可以這樣寫:

//撥通電話

        void dial(string phoneNumber);

        //通話

        void chat(object o);       

        //通話完畢掛話

        void huagup();

這是書中一段源代碼,我開始認爲這個接口是符合單一職責原則的,但是仔細分析後,發現它其實包含了兩個職責:一個是協議管理,一個是數據傳送。dial()和hangup()兩個方法實現的是協議管理,分別負責撥號接通和掛機;chat()實現的是數據的傳送。那麼我們在現實生活當中協議接通和數據傳送都會發生變化,所以我們可以將接口拆分成兩個接口,類圖如下:

 

這個類圖就完全符合單一職責原則的要求了,每個接口職責分明,結構清晰,那麼我們的手機類要把ConnectionManager和DataTransfer組合一塊才能使用。組合是一種強耦合關係,都有共同的生命週期,我們使用這個強耦合關係不僅不如使用接口實現的方式,並且還增加了類的複雜性。下面我們就來修改一下這個類圖:

 

這樣子設計就變成了,一個類實現了兩個接口,把兩個職責融合在一個類中。

那麼通過上面的例子,說明單一職責原則有什麼好處呢?引用書上一段話吧!

(1)       類的複雜性降低,實現什麼職責都有清晰明確的定義。

(2)       可讀性提高。

(3)       可維護性提高。

(4)       變更引起的風險降低。

注意:

單一職責原則提供了一個編寫程序的標準,用“職責”或“變化原因”來衡量接口或類設計得是否優良,但是“職責”或“變化原因”都是不可度量的,因項目而異,因環境而異。

對於接口,我們在設計得時候一定要做到單一,但是對於實現類就需要考慮多方面因素了。生搬硬套單一職責原則會引起類的劇增,給維護帶來非常多的麻煩,過分細分類的職責也會人爲地增加系統的複雜性。

還有就是類的單一職責可能會受很多因素的制約。比如說:項目工期,成本,人員技術水平,硬件情況,網絡情況等因素。所以說對於單一職責原則,引用作者一句話就是:接口一定要做到單一職責,類的設計儘量要做到只有一個原因引起變化。

 

發佈了25 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章