日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

1.单一职责原则(Single Responsibility Principle)

發布時間:2025/4/14 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 1.单一职责原则(Single Responsibility Principle) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.定義

  就一個類而言,應該僅有一個引起它變化的原因。

2.定義解讀

  這是六大原則中最簡單的一種,通俗點說,就是不存在多個原因使得一個類發生變化,也就是一個類只負責一種職責的工作。

3.優點

  • 類的復雜度降低,一個類只負責一個功能,其邏輯要比負責多項功能簡單的多;
  • 類的可讀性增強,閱讀起來輕松;
  • 可維護性強,一個易讀、簡單的類自然也容易維護;
  • 變更引起的風險降低,變更是必然的,如果單一職責原則遵守的好,當修改一個功能時,可以顯著降低對其他功能的影響。

4.問題提出

  假設有一個類C,它負責兩個不同的職責:職責P1和P2。當職責P1需求發生改變而需要修改類C時,有可能會導致原本運行正常的職責P2功能發生故障。

5.解決方案

  遵循單一職責原則。分別建立兩個類C1、C2,使C1完成職責P1,C2完成職責P2。這樣,當修改類C1時,不會使職責P2發生故障風險;同理,當修改C2時,也不會使職責P1發生故障風險。

  說到這里,大家會覺得這個原則太簡單了。稍有經驗的程序員,即使沒有聽說過單一職責原則,在設計軟件時也會自覺的遵守這一重要原則。在實際的項目開發中,誰也不希望因為修改了一個功能導致其他的功能發生故障。而避免出現這一問題的方法便是遵循單一職責原則。雖然單一職責原則如此簡單,并且被認為是常識,即便是經驗豐富的程序員寫出的程序,也會有違背這一原則的代碼存在。為什么會出現這種現象呢?因為有職責擴散。實際項目中,因為某種原因,職責P被分化為粒度更細的職責P1和P2。

  比如:類C只負責一個職責P,這樣設計是符合單一職責原則的。后來由于某種原因,也許是需求變更了,也許是客戶提出了新的功能,需要將職責P細分為粒度更細的職責P1,P2,這時如果要使程序遵循單一職責原則,需要將類C也分解為兩個類C1和C2,分別負責P1、P2兩個職責。但是在程序已經寫好的情況下,這樣做有時候需要花費更多的工作量。在項目工期緊張的情況下,我們通常會簡單的修改類C,用它來負責兩個職責,雖然這樣做有悖于單一職責原則。(這樣做的風險在于職責擴散的不確定性,因為在未來可能會擴散出P1,P2,P3,P4……Pn。所以記住,在職責擴散到我們無法控制的程度之前,立刻對代碼進行重構。)

6.示例

  說一個和我們密切相關的場景:員工的工資計算。剛開始的時候,我們會新建一個員工類,在員工類里面有一個計算工資的方法,代碼如下所示:

class Employee {func calculateSalary(name: String){print("\(name)的工資是100");} }//調用 let employee = Employee(); employee.calculateSalary("小明"); //打印:小明的工資是100

  產品上線后,問題出來了,因為員工的崗位不同,工資的計算是不一樣的。修改時如果遵循單一職責原則,需要將Employee類細分為總監類Director、經理類Manager、普通員工類Staff,這三個類的實現代碼和Employee類一樣,只是方法calculateSalary有所不同。實際項目中,可以考慮將Employee定義為協議,Director、Manager、Staff實現該協議,這樣以后擴展其他類型的職位增加相應的類即可。

protocol Employee {func calculateSalary(name: String); }//總監 class Director: Employee {func calculateSalary(name: String){print("\(name)總監的工資是10000");} }//經理 class Manager: Employee {func calculateSalary(name: String){print("\(name)經理的工資是1000");} }//普通員工 class Staff: Employee {func calculateSalary(name: String){print("\(name)員工的工資是100");} }//調用 let director = Director(); director.calculateSalary("張三"); //打印:張三總監的工資是10000 let manager = Manager(); manager.calculateSalary("李四"); //打印:李四經理的工資是1000 let staff = Staff(); staff.calculateSalary("王五"); //打印:王五員工的工資是100

  上面的修改方式是在遵循單一職責原則下進行的,從修改中,我們可以看到,這樣修改的工作量相對較大,需要新增不同的崗位類,還需要修改調用代碼。實際項目開發中,我們可能會采取如下兩種方式:

  【方式一】:直接修改Employee類里面的calculateSalary方法,在這里,我們需要對calculateSalary方法增加一個參數,以標識員工的崗位。

  修改后的calculateSalary方法如下所示:

enum EmployeeType {case Director;case Manager;case Staff; }class Employee {func calculateSalary(name: String, employeeType: EmployeeType){if .Director == employeeType{print("\(name)總監的工資是10000");}else if .Manager == employeeType{print("\(name)經理的工資是1000");}else if .Staff == employeeType{print("\(name)的工資是100");}} }//調用 let employee = Employee(); employee.calculateSalary("張三", employeeType: .Director); //打印:張三總監的工資是10000 employee.calculateSalary("李四", employeeType: .Manager); //打印:李四經理的工資是1000 employee.calculateSalary("王五", employeeType: .Staff); //打印:王五的工資是100

  從上面可以看到,這種修改方式相對要簡單的多,是直接在方法級別上違背了單一職責原則,雖然修改起來最簡單,但隱患卻也是最大的。假設有一天需要將總監分為財務總監和研發總監,則又需要修改Employee類的calculateSalary方法,而對原有代碼的修改會對已有功能帶來風險(可能會存在遺漏或者疏忽)。

  【方式二】:在Employee類中新增不同崗位的工資計算方法,.h文件中新加的方法定義如下所示:

class Employee {func directorCalculateSalary(name: String){print("\(name)總監的工資是10000");}func managerCalculateSalary(name: String){print("\(name)經理的工資是1000");}func staffCalculateSalary(name: String){print("\(name)的工資是100");} }//調用 let employee = Employee(); employee.directorCalculateSalary("張三"); //打印:張三總監的工資是10000 employee.managerCalculateSalary("李四"); //打印:李四經理的工資是1000 employee.staffCalculateSalary("王五"); //打印:王五的工資是100

  可以看到,方式二沒有改動原來的方法,而是在類中新加了三個方法,這樣雖然也違背了單一職責原則,但在方法級別上卻是符合單一職責原則,因為它并沒有改變原來方法的代碼。

7.示例總結

  上面三種方式各有優缺點,那么在實際編程中,該采用哪一種呢?這個問題沒有標準答案,需要根據實際情況來確定。

?

轉載于:https://www.cnblogs.com/LeeGof/p/5704014.html

總結

以上是生活随笔為你收集整理的1.单一职责原则(Single Responsibility Principle)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。