教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢(xún)/投訴熱線(xiàn):400-618-4000

設(shè)計(jì)模式-責(zé)任鏈

更新時(shí)間:2018年12月07日11時(shí)46分 來(lái)源:傳智播客 瀏覽次數(shù):

# 設(shè)計(jì)模式-責(zé)任鏈

設(shè)計(jì)模式-責(zé)任鏈

## 定義

? 責(zé)任鏈模式(Chain of Responsibility)使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免請(qǐng)求的發(fā)送者和接受者之間的耦合關(guān)系。將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求,直到有對(duì)象處理完它為止。

? 責(zé)任:當(dāng)接收者收到一個(gè)請(qǐng)求后就有責(zé)任要把這個(gè)請(qǐng)求處理完,如果它處理不了,則可以轉(zhuǎn)給其它處理者。

? 鏈:請(qǐng)求最終得到處理完成這個(gè)過(guò)程所經(jīng)歷過(guò)的每個(gè)處理者連接起來(lái)形成一條鏈。

類(lèi)型:行為類(lèi)模式

## 特點(diǎn)

1. 接收請(qǐng)求的對(duì)象連接成一條鏈,對(duì)象之間存在層級(jí)關(guān)系。

2. 這些對(duì)象可處理請(qǐng)求,也可傳遞請(qǐng)求,直到有對(duì)象處理該請(qǐng)求

## 責(zé)任鏈模式涉及到的角色

1. 抽象處理者角色(Handler):定義了處理請(qǐng)求的接口或者抽象類(lèi),提供了處理請(qǐng)求的方法(handlleRequest)和設(shè)置下一個(gè)處理者(nextHandler)的方法

2. 具體處理者角色(ConcreteHandler):實(shí)現(xiàn)或者繼承抽象這角色,具體邏輯根據(jù)實(shí)際的架構(gòu)來(lái)定

## 責(zé)任鏈模式類(lèi)圖

![class](pics\class.png)

## 實(shí)例:?jiǎn)T工晉級(jí)流程處理

### 分析

? 員工晉級(jí)流程涉及多個(gè)部門(mén)的審批。我們可以用UML的活動(dòng)圖來(lái)表示

![員工晉升流程圖](pics\員工晉升流程圖.png)

責(zé)任鏈模式是一種行為模式,因此我們可以給上圖中UML圖中所涉及到的每個(gè)處理行為都定義成一個(gè)真正的處理類(lèi)

### 代碼實(shí)現(xiàn)

#### 1. 項(xiàng)目目錄結(jié)構(gòu)

![工程目錄結(jié)構(gòu)](pics\工程目錄結(jié)構(gòu).png)

#### 2. 創(chuàng)建抽象處理者角色

Hanlder類(lèi)

```java

package com.itheima.demo.handler;

public abstract class Handler {

// 下個(gè)處理器

private Handler nextHandler;

// 處理當(dāng)下的請(qǐng)求

public abstract void handleRequest();

// 獲取下個(gè)處理器

public Handler getNextHandler() {

return nextHandler;

}

// 設(shè)置下個(gè)處理器

public void setNextHandler(Handler nextHandler) {

this.nextHandler = nextHandler;

}

}

```

#### 3. 創(chuàng)建各個(gè)具體處理者角色

* 員工發(fā)起晉級(jí)申請(qǐng)?zhí)幚?/p>

```java

package com.itheima.demo.handler;

/**

* 員工晉升申請(qǐng)

*

*/

public class EmpRequestPromotionHandler extends Handler {

/**

* 處理提交晉升申請(qǐng)

*/

@Override

public void handleRequest() {

System.out.println("員工提交晉升申請(qǐng)");

// 由下個(gè)處理者來(lái)處理

getNextHandler().handleRequest();

}

}

```

* 直屬領(lǐng)導(dǎo)的處理

```java

package com.itheima.demo.handler;

/**

* 直屬領(lǐng)導(dǎo)的處理

*

*/

public class Level1Handler extends Handler {

/**

* 直屬領(lǐng)導(dǎo)的處理: 填寫(xiě)晉升人員基本情況

*/

@Override

public void handleRequest() {

System.out.println("--直屬領(lǐng)導(dǎo)的處理: 填寫(xiě)晉升人員基本情況");

// 處理完后由下個(gè)處理者處理

getNextHandler().handleRequest();

}

}

```

* 部門(mén)總監(jiān)的處理

```java

package com.itheima.demo.handler;

/**

* 部門(mén)總監(jiān)的處理

*

*/

public class Level2Handler extends Handler {

/**

* 部門(mén)總監(jiān)的處理: 填寫(xiě)晉升人員基本情況

*/

@Override

public void handleRequest() {

System.out.println("----部門(mén)總監(jiān)的處理: 進(jìn)入能力業(yè)績(jī)考核");

int random = (int)(Math.random() * 10);

if(random < 9) {

System.out.println("----考核通過(guò)");

// 交給下個(gè)處理者處理

getNextHandler().handleRequest();

}else {

System.out.println("----考核沒(méi)通過(guò)");

System.out.println("流程結(jié)束");

}

}

}

```

* 執(zhí)行總裁的處理

```java

package com.itheima.demo.handler;

/**

* 執(zhí)行總裁的處理

*

*/

public class Level3Handler extends Handler {

/**

* 根據(jù)組織架構(gòu)判定是否晉升

*/

@Override

public void handleRequest() {

System.out.println("------執(zhí)行總裁的處理:根據(jù)組織架構(gòu)判定是否晉升");

int random = (int)(Math.random() * 10);

if(random < 9) {

System.out.println("------審批通過(guò)");

// 考核通過(guò),交給下個(gè)處理者處理

getNextHandler().handleRequest();

}else {

System.out.println("------審批沒(méi)通過(guò)");

System.out.println("流程結(jié)束");

}

}

}

```

* 人事部的處理

```java

package com.itheima.demo.handler;

/**

* 人事部的處理

*/

public class HR1Handler extends Handler {

/**

* 是否符合晉升標(biāo)準(zhǔn)

*/

@Override

public void handleRequest() {

System.out.println("--------人事部的處理: 是否符合晉升標(biāo)準(zhǔn)");

int random = (int)(Math.random() * 10);

if(random < 9) {

System.out.println("--------審批通過(guò)");

// 考核通過(guò),交給下個(gè)處理者處理

getNextHandler().handleRequest();

}else {

System.out.println("--------審批沒(méi)通過(guò)");

System.out.println("流程結(jié)束");

}

}

}

```

* 人事總裁的處理

```java

package com.itheima.demo.handler;

/**

* 人事總裁的處理

*/

public class HR2Handler extends Handler {

/**

* 是否符合晉升標(biāo)準(zhǔn)審批

*/

@Override

public void handleRequest() {

System.out.println("----------人事總裁的處理: 是否符合晉升標(biāo)準(zhǔn)審批");

int random = (int)(Math.random() * 10);

if(random < 9) {

System.out.println("----------審批通過(guò)");

// 考核通過(guò),交給下個(gè)處理者處理

getNextHandler().handleRequest();

}else {

System.out.println("----------審批沒(méi)通過(guò)");

System.out.println("流程結(jié)束");

}

}

}

```

* 人事部通知處理

```java

package com.itheima.demo.handler;

/**

* 人事部的處理2

*/

public class HRAdviceHandler extends Handler {

/**

* 通知晉升處理

*/

@Override

public void handleRequest() {

System.out.println("--------------人事部的處理2:通知晉升人員確認(rèn)");

// 處理完后由下個(gè)處理者處理

getNextHandler().handleRequest();

}

}

```

* 員工簽名的處理

```java

package com.itheima.demo.handler;

/**

* 員工簽名的處理

*/

public class EmpSignUpHandler extends Handler {

/**

* 員工簽名的處理

*/

@Override

public void handleRequest() {

System.out.println("----------------員工的處理2:簽字確認(rèn)");

// 處理完后由下個(gè)處理者處理

getNextHandler().handleRequest();

}

}

```

* 人事部通告與歸檔的處理

```java

package com.itheima.demo.handler;

/**

* 人事部通告與歸檔的處理

*/

public class HRAnnouncementHandler extends Handler {

/**

* 通告與歸檔

*/

@Override

public void handleRequest() {

System.out.println("------------------人事部的處理3:通告與歸檔");

System.out.println("全部流程走完");

}

}

```

#### 4. 創(chuàng)建調(diào)用類(lèi)

```java

package com.itheima.demo;

import com.itheima.demo.handler.EmpRequestPromotionHandler;

import com.itheima.demo.handler.EmpSignUpHandler;

import com.itheima.demo.handler.HR1Handler;

import com.itheima.demo.handler.HR2Handler;

import com.itheima.demo.handler.HRAdviceHandler;

import com.itheima.demo.handler.HRAnnouncementHandler;

import com.itheima.demo.handler.Handler;

import com.itheima.demo.handler.Level1Handler;

import com.itheima.demo.handler.Level2Handler;

import com.itheima.demo.handler.Level3Handler;

public class Client {

public static void main(String[] args) {

// 構(gòu)建每個(gè)行為的處理器

Handler empHandler = new EmpRequestPromotionHandler();

Handler level1Handler = new Level1Handler();

Handler level2Handler = new Level2Handler();

Handler level3Handler = new Level3Handler();

Handler hr1Handler = new HR1Handler();

Handler hr2Handler = new HR2Handler();

Handler hrAdviceHandler = new HRAdviceHandler();

Handler empSignUpHandler = new EmpSignUpHandler();

Handler hrAnnouncementHandler = new HRAnnouncementHandler();

// 設(shè)置每個(gè)處理的下個(gè)處理器

empHandler.setNextHandler(level1Handler);

level1Handler.setNextHandler(level2Handler);

level2Handler.setNextHandler(level3Handler);

level3Handler.setNextHandler(hr1Handler);

hr1Handler.setNextHandler(hr2Handler);

hr2Handler.setNextHandler(hrAdviceHandler);

hrAdviceHandler.setNextHandler(empSignUpHandler);

empSignUpHandler.setNextHandler(hrAnnouncementHandler);

// 員工發(fā)起晉級(jí)申請(qǐng)

empHandler.handleRequest();

}

}

```

#### 5. 運(yùn)行效果

![result](pics\result.png)

## 總結(jié)

? 責(zé)任鏈模式通過(guò)建立一條鏈來(lái)組織請(qǐng)求的處理者,請(qǐng)求將沿著鏈進(jìn)行傳遞,而請(qǐng)求發(fā)送者無(wú)須知道請(qǐng)求在何時(shí)、何處以及如何被處理,實(shí)現(xiàn)了請(qǐng)求發(fā)送者與處理者的解耦。在實(shí)際軟件開(kāi)發(fā)中,如果遇到有多個(gè)對(duì)象可以處理同一請(qǐng)求時(shí)可以考慮使用職責(zé)鏈模式,一般都可以用來(lái)保證請(qǐng)求得到最終的執(zhí)行。

0 分享到:
和我們?cè)诰€(xiàn)交談!