設(shè)計模式原則之單一職責(zé)原則

定義

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

應(yīng)該有且僅有一個原因引起類的變更逢唤。


優(yōu)點

降低類的復(fù)雜性

每個類實現(xiàn)單一職責(zé),并且單一職責(zé)都有清楚明確的定義卵牍,復(fù)雜性當(dāng)然降低。

提高可讀性?

類的復(fù)雜性降低了厕倍,當(dāng)然提高了可讀性了兴蒸。

提高可維護(hù)性?

類的復(fù)雜性降低盾饮,可讀性好,當(dāng)然好維護(hù)既绩。

易于測試

測試單一目標(biāo)的類只需要很少的測試類概龄。讓“用測試替代文檔” “self documentation by tests”變得更加容易

易于調(diào)試

在一個單一職責(zé)類找到問題是一件更容易的事情。


變更引起的風(fēng)險降低饲握,變更是必不可少的私杜,如果接口的單一職責(zé)做的好蚕键,一個接口修改只對相應(yīng)的實現(xiàn)類有影響,對其它的接口沒有影響衰粹,這對系統(tǒng)的擴展性锣光,維護(hù)性都是有好處的。


類的單一職責(zé)原則

一般一個對象可以分為屬性行為二部分铝耻,所以在類的設(shè)計時誊爹,我們一般把對象的屬性抽象成一個BO(Business Object,業(yè)務(wù)對象),把對象的行為抽象成一個Biz(Business Logic瓢捉,業(yè)務(wù)邏輯)频丘。


產(chǎn)生原因

沒有任何的程序設(shè)計人員不清楚應(yīng)該寫出高內(nèi)聚低耦合的程序,但是很多耦合常常發(fā)生在不經(jīng)意之間泡态,其原因就是:職責(zé)擴散:因為某種原因搂漠,某一職責(zé)被分化為顆粒度更細(xì)的多個職責(zé)了

解決辦法

遵守單一職責(zé)原則,將不同的職責(zé)封裝到不同的類或模塊中某弦。


場景模擬

我們需要創(chuàng)作一個論壇桐汤,需要發(fā)布主題和回帖功能

場景模擬UML 圖


場景模擬UML圖

簡單代碼

@protocol Thread<NSObject>

-(void)addReplayMessage;

@end

#import "Thread.h"

@protocol Forum<NSObject>

-(void)addThread:(id<Thread>)thread;

-(void)addReplayMessage;

@end

#import "Forum.h"

@interface ForumObject : NSObject<Forum>

@end

#import "ForumObject.h"

@interface ForumObject()

@property (nonatomic,strong) id<Thread>thread;

@end@implementation ForumObject

-(void)addThread:(id<Thread>)thread{

? ? self.thread = thread;

}

-(void)addReplayMessage{

? ? [self.thread addReplayMessage];

}

@end

#import "Thread.h"

@interface ThreadObject : NSObject<Thread>

@property (nonatomic,strong) NSString *name;

@end

#import "ThreadObject.h"

@implementation ThreadObject

-(void)addReplayMessage{

? ? NSLog(@"%@ 回復(fù)信息",self.name);

}

@end


測試代碼

id<Forum> forumObject = [ForumObject new];

ThreadObject * threadobject = [ThreadObject new];

threadobject.name =@"單一職責(zé)原則";

[forumObject addThread:threadobject];

[forumObject addReplayMessage];

測試結(jié)果

2018-04-04 14:39:55.425610+0800 設(shè)計模式原則[90446:6274362] 單一職責(zé)原則 回復(fù)信息


分析

我們都知道一個論壇的結(jié)構(gòu)一般是

forum------->Thread----------->Message

一個論壇Forum中有多個Thread ,一個Thread 有多個回帖和跟帖。

根據(jù)這個層次結(jié)構(gòu)靶壮,forum 增加回帖的功能有點太寬了怔毛,這個功能應(yīng)該屬于Thread的


代碼重構(gòu)

#import "Thread.h"

@protocol ForumNew<NSObject>

-(void)addThread:(id<NSObject>)thread;

@end

#import "ForumNew.h"

@interface ForumNewObject : NSObject<ForumNew>

@end

#import "ForumNewObject.h"

@interface ForumNewObject()

@property (nonatomic,strong) id<Thread>thread;

@end

@implementation ForumNewObject-

(void)addThread:(id<Thread>)thread{

? ? self.thread = thread;

}

@end

測試代碼

?id<ForumNew> forumObject= [ForumNewObject new];

? ?ThreadObject * threadobject = [ThreadObject new];

? ? threadobject.name =@"單一職責(zé)原則";

? ? [forumObject addThread:threadobject];

? ? [threadobject addReplayMessage];

結(jié)果

2018-04-04 14:50:13.955267+0800 設(shè)計模式原則[93059:6286368] 單一職責(zé)原則 回復(fù)信息

其實重構(gòu)代碼就是講回帖的功能從forum拿到了Thread中,代碼很簡單腾降,就是需要體會下拣度。

上述問題產(chǎn)生的原因是因為當(dāng)時我們把論壇的Thread和Message都當(dāng)做論壇的一個功能。由于后期業(yè)務(wù)變更螃壤,導(dǎo)致Thread ?和Message 需要劃分為更細(xì)致蜡娶。


如何識別SRP被破壞?

類有太多依賴

類的構(gòu)造器有太多參數(shù)映穗,意味著測試有太多依賴,需要制造mock太多測試輸入?yún)?shù)幕随,通常意味著已經(jīng)破壞SRP了蚁滋。

方法有太多參數(shù)

類似類的構(gòu)造器,方法參數(shù)意味著依賴赘淮。

測試類變得復(fù)雜

如果測試有太多變量辕录,意味著這個類有太多職責(zé)。

類或方法太長

如果方法太長梢卸,意味著內(nèi)容太多走诞,職責(zé)過多。

一個類不超過 200-250

描述性名稱

如果你需要描述你的類 方法或包蛤高,比如使用"xxx和xxx"這種語句蚣旱,意味著可能破壞了SRP.

低聚合Cohesion的類

聚合Cohesion是一個很重要的概念碑幅,雖然聚合是有關(guān)結(jié)構(gòu)概念,但是聚合和SRP非常相關(guān)塞绿,如前面論壇案例沟涨,如果一個類不代表一個高聚合,意味著低凝聚low Cohesion异吻,它就可能意味破壞SRP裹赴。一個低凝聚的特點:

一個類有兩個字段,其中一個字段被一些方法使用诀浪;另外一個字段被其他方法使用棋返。

在一個地方改動影響另外一個地方

如果在一個代碼地方加入新功能或只是簡單重構(gòu),卻影響了其他不相關(guān)的地方雷猪,意味著這個地方代碼可能破壞了SRP.

獵槍效果Shotgun Effect

如果一個小的改變引起一發(fā)動全身睛竣,這意味SRP被破壞了。

不能夠封裝模塊

比如使用Spring框架春宣,你使用@Configuration or XML 配置酵颁,如果你不能在一個配置中封裝一個Bean。意味著它有太多職責(zé)月帝,Spring配置應(yīng)該隱藏內(nèi)部bean躏惋,暴露最少接口,如果你因為多個原因需要改變Spring配置嚷辅,可能破壞了SRP.


借鑒博客

單一職責(zé)原則(SRP)

六大設(shè)計原則之單一職責(zé)原則

源代碼地址

下一篇博客

設(shè)計原則之迪米特原則

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末簿姨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子簸搞,更是在濱河造成了極大的恐慌扁位,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趁俊,死亡現(xiàn)場離奇詭異域仇,居然都是意外死亡,警方通過查閱死者的電腦和手機寺擂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門暇务,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人怔软,你說我怎么就攤上這事垦细。” “怎么了挡逼?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵括改,是天一觀的道長。 經(jīng)常有香客問我家坎,道長嘱能,這世上最難降的妖魔是什么吝梅? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮焰檩,結(jié)果婚禮上憔涉,老公的妹妹穿的比我還像新娘。我一直安慰自己析苫,他們只是感情好兜叨,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著衩侥,像睡著了一般国旷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茫死,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天跪但,我揣著相機與錄音,去河邊找鬼峦萎。 笑死屡久,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的爱榔。 我是一名探鬼主播被环,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼详幽!你這毒婦竟也來了筛欢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤唇聘,失蹤者是張志新(化名)和其女友劉穎版姑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迟郎,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡剥险,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了宪肖。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炒嘲。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖匈庭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浑劳,我是刑警寧澤阱持,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站魔熏,受9級特大地震影響衷咽,放射性物質(zhì)發(fā)生泄漏鸽扁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一镶骗、第九天 我趴在偏房一處隱蔽的房頂上張望桶现。 院中可真熱鬧,春花似錦鼎姊、人聲如沸骡和。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽慰于。三九已至,卻和暖如春唤衫,著一層夾襖步出監(jiān)牢的瞬間婆赠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工佳励, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留休里,地道東北人。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓赃承,卻偏偏與公主長得像妙黍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子楣导,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理废境,服務(wù)發(fā)現(xiàn),斷路器筒繁,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉噩凹,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,686評論 0 9
  • 定義 The dependency of one class to another one should depe...
    充滿活力的早晨閱讀 484評論 0 1
  • 這個世界有多美好,這個世界就有多糟糕毡咏。
    凌凌魕閱讀 177評論 0 0
  • “春游去嘍驮宴!”同學(xué)們像一群快樂的小鳥,在老師的帶領(lǐng)下興高采烈的上了大巴車呕缭。 在大巴車上堵泽,我們認(rèn)識了周...
    2e45075fd084閱讀 292評論 2 0