定義
一個類只負責一項職責
?
職責擴散
什么叫職責擴散,就是職責再進行細化,就拿公司來說,好比客戶的需求,需求是不斷變化的,而且存在極大的不確定性,說不定哪天上司找到你要重新細化某個需求
所以最好在職責擴散到我們無法控制的程度之前,立刻對代碼進行重構
?
栗子
我們先下面這段代碼:
class Animal:def __init__(self,name):self.name = namedef breathe(self):print('%s用肺呼吸'%self.name)niu = Animal('小奶牛')
zhu = Animal('小白豬')niu.breathe()
zhu.breathe()
? 我們很快就能從上面代碼中發現一些邏輯上的錯誤,因為不是所有的動物都是用肺呼吸,有的使用腮呼吸的,應該將Animal類細分為陸生動物類Terrestrial,水生動物類Aquatic,代碼如下:
class Animal:def __init__(self,name):self.name = nameclass Terrestrial(Animal):def breathe(self):print('%s 用肺呼吸'%self.name)class Aquatic(Animal):def breathe(self):print('%s 用腮呼吸'%self.name)c = Terrestrial('小花貓')
c.breathe()fish = Aquatic('美人魚')
fish.breathe()
? 我們看到上面代碼的實現就是動物類分出兩類,并把呼吸的方法寫入的派生類里,好!這樣做是沒問題的,那看看下面這段代碼:
class BreatheBehavior:def breathe(self):passclass LungBreathe(BreatheBehavior):def breathe(self):print('用肺呼吸')class CheekBreathe(BreatheBehavior):def breathe(self):print('用腮呼吸')class Animal:def __init__(self,name,breatheP):self.name = nameself.BreatheParam = breathePdef performBreathe(self):self.BreatheParam.breathe()class Terrestrial(Animal):def __init__(self,name,breatheP=LungBreathe()):super(Terrestrial,self).__init__(name,breatheP)class Aquatic(Animal):def __init__(self,name,breatheP=CheekBreathe()):super(Aquatic,self).__init__(name,breatheP)c = Terrestrial('小花貓')
c.performBreathe()fish = Aquatic('美人魚')
fish.performBreathe()
? 我們發現第二種方式,則像是用接口的形式實現了某個行為的類化,你可能會想,第二種方法的代碼實現明顯長的多,我為什么要用第二種方式。
在今天的這個例子,毫無疑問是第一方法簡單,那我們先來看看用單一職責原則的目的吧:
- 目的
- 可以降低類的復雜度,一個類只負責一項職責,其邏輯肯定要比負責多項職責簡單的多
- 提高類的可讀性,提高程序的可維護性
- 變更引起的風險降低,變更是必然的,如果單一職責原則遵守的好,當修改一個功能時,可以顯著降低對其他功能的影響
- 單一職責原則同時也適用于模塊化的程序設計
好!所以單一職責的核心無非就是降低復雜度和提高可讀性以及可擴展性,假如你把要動物的種類細化再細化,按照第一種方法--你是不是要在派生類重寫多個呼吸方法?但是動物的呼吸方式無非就是這幾種,所以第二種方法更適合復雜的場合,所以每種方法因場景而異,自己把握!
?
?????????????????????????????? 歡迎大家對我的博客內容提出質疑和提問!謝謝
?
????????????????? 筆者:拍省先生