成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

單一職責(zé)到底是什么?十分鐘帶你掌握!

開(kāi)發(fā)
在日常開(kāi)發(fā)工作中,經(jīng)常會(huì)聽(tīng)到有經(jīng)驗(yàn)的技術(shù)念叨xxx需要注意單一職責(zé),那么,什么是單一職責(zé)?如何做才能保證職責(zé)單一?這篇文章幫你分析透。

在日常開(kāi)發(fā)工作中,經(jīng)常會(huì)聽(tīng)到有經(jīng)驗(yàn)的技術(shù)念叨xxx需要注意單一職責(zé),那么,什么是單一職責(zé)?如何做才能保證職責(zé)單一?這篇文章幫你分析透。

什么是單一職責(zé)?

關(guān)于單一職責(zé),看過(guò)很多版本的解釋,這里歸納最常見(jiàn)的三個(gè)版本:

  • 版本一:一個(gè)類只有一個(gè)引起變化的原因
  • 版本二:一個(gè)類都應(yīng)該只負(fù)責(zé)一項(xiàng)職責(zé)
  • 版本三:一個(gè)類只能干一件事情

哪個(gè)版本的解釋比較合理呢?

單一職責(zé)原則,英文是:Single responsibility principle(SRP),是 Robert C. Martin提出的 SOLID原則中的一種,所以,我們先看看 作者對(duì)單一職責(zé)原則的描述,這里摘取了作者關(guān)于單一職責(zé)的原文:

The Single Responsibility Principle (SRP) states that
each software module should have one and only one reason to change.

原文翻譯為:?jiǎn)我宦氊?zé)原則指出,任何一個(gè)軟件模塊都應(yīng)該有一個(gè)且只有一個(gè)修改的理由。

定義看起來(lái)很?chē)?yán)謹(jǐn),但似乎和現(xiàn)實(shí)是相沖突的,因?yàn)檐浖O(shè)計(jì)本身就是一門(mén)關(guān)注長(zhǎng)期變化的學(xué)問(wèn),變化是軟件中最常見(jiàn)不過(guò)的問(wèn)題,在現(xiàn)實(shí)環(huán)境中,軟件系統(tǒng)為了滿足用戶和所有者的要求,勢(shì)必會(huì)作出各種修改,而系統(tǒng)的用戶或者所有者就是該設(shè)計(jì)原則所指的"被修改的原因"。

于是乎,作者又重新把單一職責(zé)描述為:

The single responsibility principle states that every module
or class should have responsibility over a single part of 
the functionality provided by the software, and that 
responsibility should be entirely encapsulated by the class.

原文翻譯為:?jiǎn)我宦氊?zé)原則指出,每個(gè)模塊或類應(yīng)該只負(fù)責(zé)軟件所提供功能的一部分,并且這個(gè)職責(zé)應(yīng)該完全被該類封裝。

在這個(gè)定義中,每個(gè)模塊或者類只負(fù)責(zé)軟件的一部分功能,那這一部分是多少呢?這部分功能是否可以包含不同類型的行為呢?比如,電商中的訂單和物流都可以叫做電商的一部分功能,但是他們?cè)跇I(yè)務(wù)意義上顯然是不同的領(lǐng)域,因此,該定義缺乏了定性。

于是乎,作者再次修改了單一職責(zé)的定義:

Each module should only be responsible to one actor.

原文翻譯為:任何一個(gè)軟件模塊都應(yīng)該只對(duì)某一類行為者負(fù)責(zé)

這個(gè)定義,只要是能歸結(jié)成一類的行為,都可以屬于某個(gè)模塊的功能,這樣定義看起來(lái)更符合現(xiàn)實(shí)業(yè)務(wù)的語(yǔ)意。

軟件模塊是什么?

在上述單一職責(zé)幾個(gè)定義中都提到了軟件模塊,那么,軟件模塊到底是什么呢?

軟件模塊(Software Module)是指軟件系統(tǒng)中的一個(gè)獨(dú)立單元,它包含一組相關(guān)的功能和數(shù)據(jù),這些模塊是通過(guò)封裝數(shù)據(jù)和功能來(lái)實(shí)現(xiàn)的,以便實(shí)現(xiàn)更高的代碼復(fù)用性、可維護(hù)性和可擴(kuò)展性。通常具有以下特點(diǎn):

  • 獨(dú)立性:模塊是相對(duì)獨(dú)立的代碼單元,可以單獨(dú)開(kāi)發(fā)、測(cè)試和部署。模塊的獨(dú)立性提高了系統(tǒng)的靈活性,使得各個(gè)模塊可以獨(dú)立演化和更新,而不影響其他模塊。
  • 封裝性:模塊內(nèi)部的數(shù)據(jù)和實(shí)現(xiàn)細(xì)節(jié)對(duì)外界隱藏,只通過(guò)公開(kāi)的接口與其他模塊進(jìn)行交互。封裝性提高了代碼的安全性和可維護(hù)性。
  • 職責(zé)單一:每個(gè)模塊通常只負(fù)責(zé)一組相關(guān)的功能,這有助于遵循單一職責(zé)原則,使得模塊更加易于理解和維護(hù)。
  • 可重用性:模塊設(shè)計(jì)得當(dāng),可以在不同的項(xiàng)目中重復(fù)使用,提高了開(kāi)發(fā)效率和代碼質(zhì)量。
  • 可替換性:模塊通過(guò)標(biāo)準(zhǔn)化的接口與外界交互,可以在不影響其他部分的前提下替換或更新某個(gè)模塊。

為了更好地說(shuō)明軟件模塊,這里以一個(gè)電商系統(tǒng)為例,它可能包含以下幾個(gè)模塊:

(1) 用戶管理模塊:

  • 功能:處理用戶的注冊(cè)、登錄、個(gè)人信息管理等。
  • 接口:提供用戶注冊(cè)、登錄、信息更新等服務(wù)。

(2) 訂單管理模塊:

  • 功能:處理訂單的創(chuàng)建、更新、查詢等。
  • 接口:提供訂單創(chuàng)建、訂單狀態(tài)更新、訂單查詢等服務(wù)。

(3) 支付處理模塊:

  • 功能:處理訂單的支付、退款等。
  • 接口:提供支付請(qǐng)求、支付狀態(tài)查詢、退款等服務(wù)。

(4) 庫(kù)存管理模塊:

  • 功能:處理商品的庫(kù)存查詢、更新等。
  • 接口:提供庫(kù)存查詢、庫(kù)存更新等服務(wù)。

單一職責(zé)示例

為了更好的說(shuō)明任何一個(gè)軟件模塊都應(yīng)該只對(duì)某一類行為者負(fù)責(zé)這個(gè)定義,下面我們通過(guò)2個(gè) Java反例來(lái)進(jìn)行演示。

反例1

假設(shè)有一個(gè) Employee員工類并且包含以下 3個(gè)方法:

public class Employee { 
  // calculatePay() 實(shí)現(xiàn)計(jì)算員工薪酬
  public Money calculatePay();
  // save() 將Employee對(duì)象管理的數(shù)據(jù)存儲(chǔ)到企業(yè)數(shù)據(jù)庫(kù)中
  public void save();
  // postEvent() 用于促銷(xiāo)活動(dòng)發(fā)布
  public void postEvent();
}

剛看上去,這個(gè)類設(shè)計(jì)得還挺符合實(shí)際業(yè)務(wù),員工有計(jì)算薪酬、保存數(shù)據(jù)、發(fā)布促銷(xiāo)等行為,但是這 3個(gè)方法對(duì)應(yīng)三類不同的行為者,計(jì)算薪酬屬于財(cái)務(wù)的行為,保存數(shù)據(jù)屬于數(shù)據(jù)管理員的行為,發(fā)布促銷(xiāo)屬于銷(xiāo)售的行為。

因此,Employee類將三類行為耦合在一起,違反了單一職責(zé)原則。假如一個(gè)普通員工不小心調(diào)用了calculatePay()方法,把每個(gè)員工的薪酬計(jì)算成了實(shí)際工資的2位,那可想而知這是一個(gè)災(zāi)難性的問(wèn)題。

如果增加新需求,要求員工能夠?qū)С鰣?bào)表,因此,需要在 Employee類中增加了一個(gè)新的方法,代碼如下:

// 導(dǎo)出報(bào)表
void exportReport();

接著需求又一個(gè)一個(gè)增加,Employee類就得一次一次的變動(dòng),這會(huì)導(dǎo)致什么結(jié)果呢?

一方面,Employee類會(huì)不斷地膨脹;另一方面,可能業(yè)務(wù)需求完全不同,卻始終需要在同一個(gè) Employee類上改動(dòng),合理嗎?

聯(lián)想一下你的日常開(kāi)發(fā),是否也有這樣的設(shè)計(jì)?把很多不同的行為都耦合到同一個(gè)類中,然后隨著業(yè)務(wù)的增加,該類急劇膨脹,最后無(wú)法維護(hù)。

該如何解決這種問(wèn)題呢?

解決這個(gè)問(wèn)題的方法有很多,特定的行為只能由特定的行為者來(lái)操作,因此,需要把 Employee類拆解成 3種行為者(財(cái)務(wù)、數(shù)據(jù)管理員、銷(xiāo)售),Employee類拆分之后的代碼如下:

// 財(cái)務(wù)行為
public class FinanceStaff {
  public Money calculatePay();
}

// 數(shù)據(jù)管理員行為
public class TechnicalStaff {
    public void save();
}

// 銷(xiāo)售行為
public class OperatorStaff {
    public String postEvent();
}

反例2

假設(shè)需要開(kāi)發(fā)一個(gè)電商系統(tǒng),其中有一個(gè) Order訂單類,負(fù)責(zé)處理訂單的創(chuàng)建、訂單的支付以及訂單的通知,代碼如下:

public class Order {

    public void createOrder() {
        // 訂單創(chuàng)建邏輯
    }

    public void processPayment() {
        // 支付處理邏輯
    }

    public void sendNotification() {
        // 發(fā)送通知邏輯
    }
}

在上述代碼中,Order類同時(shí)承擔(dān)了訂單創(chuàng)建、支付處理和通知發(fā)送的職責(zé),違反了單一職責(zé)原則,因?yàn)橐粋€(gè)類有多個(gè)引起變化的原因。

為了遵循SRP,我們需要將不同的職責(zé)分離到不同的類中,因此可以創(chuàng)建三個(gè)類:Order類負(fù)責(zé)訂單創(chuàng)建,PaymentProcessor類負(fù)責(zé)支付處理,NotificationService類負(fù)責(zé)通知發(fā)送,每個(gè)類都只承擔(dān)一個(gè)職責(zé),從而遵循了單一職責(zé)原則。代碼如下:

public class Order {
    public void createOrder() {
        // 訂單創(chuàng)建邏輯
    }
}

public class PaymentProcessor {
    public void processPayment(Order order) {
        // 支付處理邏輯
    }
}

public class NotificationService {
    public void sendNotification(Order order) {
        // 發(fā)送通知邏輯
    }
}

上面2個(gè)示例代碼的拆分都遵從了原則:因相同原因而發(fā)生變化的事物聚集在一起,因不同原因而改變的事物分開(kāi)。這就是單一職責(zé)的真正體現(xiàn),也是定義內(nèi)聚和耦合的一種方式。

總結(jié)

從作者 Robert C. Martin對(duì)單一職責(zé)的 3次定義變更,我們可以看出:

  • 單一職責(zé)原則本質(zhì)上就是要理解分離關(guān)注點(diǎn)。
  • 單一職責(zé)原則可以應(yīng)用于不同的層次,小到一個(gè)函數(shù),大到一個(gè)系統(tǒng)。
  • 軟件設(shè)計(jì)也不可能一成不變。

回歸到實(shí)際的工作中,我們可以把一個(gè)系統(tǒng)模塊看作一個(gè)單一職責(zé)的行為者,比如:訂單系統(tǒng)只關(guān)注訂單相關(guān)的行為,交易系統(tǒng)只關(guān)注交易相關(guān)的行為,我們也可以把類作為一個(gè)單一職責(zé)的行為者,比如:訂單類,把訂單相關(guān)的 CRUD聚合在一起,支付類,把支付相關(guān)的信息聚合在一起。

因此,任何一個(gè)軟件模塊都應(yīng)該只對(duì)某一類行為者負(fù)責(zé)這個(gè)定義才更適合單一職責(zé)。

最后,單一職責(zé)原則是面向?qū)ο笤O(shè)計(jì)的重要原則之一,它可以提高代碼的可維護(hù)性、可讀性和可擴(kuò)展性,在日常開(kāi)發(fā)中,遵循 SRP可以有效地降低類之間的耦合度,提高系統(tǒng)的穩(wěn)定性和靈活性,從而寫(xiě)出更高質(zhì)量的代碼。

責(zé)任編輯:趙寧寧 來(lái)源: 猿java
相關(guān)推薦

2024-07-12 09:00:00

2024-12-13 15:29:57

SpringSpringBeanJava

2024-10-25 15:56:20

2022-06-16 07:31:41

Web組件封裝HTML 標(biāo)簽

2025-01-07 12:00:00

RedisPipelineJava

2022-08-26 09:01:07

CSSFlex 布局

2024-11-07 16:09:53

2024-07-22 11:33:29

2024-08-30 10:51:51

2020-12-17 06:48:21

SQLkafkaMySQL

2019-04-01 14:59:56

負(fù)載均衡服務(wù)器網(wǎng)絡(luò)

2023-09-26 22:12:13

數(shù)據(jù)倉(cāng)庫(kù)Doris

2020-09-27 14:41:37

C語(yǔ)言編程語(yǔ)言計(jì)算機(jī)

2023-10-07 00:06:09

SQL數(shù)據(jù)庫(kù)

2020-12-09 16:41:22

LinuxIT開(kāi)發(fā)

2024-06-19 09:58:29

2021-09-07 09:40:20

Spark大數(shù)據(jù)引擎

2023-04-12 11:18:51

甘特圖前端

2012-07-10 01:22:32

PythonPython教程

2024-05-13 09:28:43

Flink SQL大數(shù)據(jù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产精品入口麻豆www | 欧美日高清视频 | 成人av网站在线观看 | 欧美日韩综合一区 | 国产精品视频在线播放 | 欧美成人一区二区三区片免费 | 久久精品av麻豆的观看方式 | 亚洲精品一二三 | 成人久久久 | 人干人人 | av日日操 | 成人区一区二区三区 | 午夜视频免费网站 | 黄a网站 | 国产欧美一区二区三区国产幕精品 | 求毛片| 国产精品亚洲综合 | 色综合网站 | av免费网站在线观看 | 国产免费一区二区 | 久久久99国产精品免费 | 91av在线视频观看 | 免费一级欧美在线观看视频 | 国产wwwcom| av综合站| 欧美电影免费观看高清 | 亚洲在线一区二区 | 亚洲永久入口 | 蜜桃视频在线观看免费视频网站www | 中文字幕第一页在线 | 国产清纯白嫩初高生在线播放视频 | 一区二区视频 | 午夜影院网站 | 国产精品久久久 | 国产 欧美 日韩 一区 | 在线中文字幕av | 精品美女在线观看视频在线观看 | 国产高清精品一区二区三区 | 国产偷久久一级精品60部 | 一区二区三区国产视频 | 欧美色综合|