设计模式学习笔记之职责链模式

今天开始打算将设计模式相关的内容进行一下梳理,同时将一些Demo记录于此。

在开始今天的学习笔记之前,我想先讲这样一个故事:某公司到了一年一度调薪的日子,对于调薪的受理由不同的职位的领导进行处理。部门经理可以直接受理1000以内的调薪,总经理可以直接受理2000以内的调薪,董事长可以受理5000以内的调薪。目前,有三位童鞋申请调薪,他们分别是 Kaisir:3000 , Zhang:5000 , liu:1500 , X-Man:10000,如果使用程序编写,我们该如何处理这种情况呢?

在这种情况下,我们的请求沿着 “部门经理 -> 总经理 -> 董事长” 的顺序依次传递,每一级受理他们权限之内的请求,若超出权限,则继续向上级申请。除了调薪之外,请假,调薪也跟此情景类似,于是对于此种情景,我们可以使用职责链模式进行处理。

任何事物都有正反两面,这个职责链模式的优缺点在哪里呢?
优点:链上的每个节点都是彼此独立的,节点无需知道整个链条的内容,只需要知道他的后继节点即可,这样很大程度降低了类与类之间的耦合关系。此外可以很自由的增加新的处理节点,无需修改之前的节点,符合开放-封闭原则。

缺点:除目标链之外,其他的节点仅仅起到传递的作用,若链过长的话,系统将被传递用的节点占掉很多的资源。

具体事例代码如下:
抽象类 Manager

[java]

package com.kaisir.designpattern.chain;

import com.kaisir.designpattern.chain.model.Request;

/**
* Created with IntelliJ IDEA.
* User: Kaisir
* Date: 13-3-23
* Time: 下午2:32
* To change this template use File | Settings | File Templates.
*/
public abstract class Manager {
private Manager nextchain;

public Manager getNextchain() {
return nextchain;
}

public void setNextchain(Manager nextchain) {
this.nextchain = nextchain;
}

public abstract void doRequest(Request request);
}

[/java]

部门经理类:

[java]

package com.kaisir.designpattern.chain;

import com.kaisir.designpattern.chain.model.Request;

/**
* Created with IntelliJ IDEA.
* User: Kaisir
* Date: 13-3-23
* Time: 下午2:35
* To change this template use File | Settings | File Templates.
*/
public class DepartmentManager extends Manager {
@Override
public void doRequest(Request request) {
if (request.getMoney()<1000){
System.out.println("Department Manager has accepted "+request.getName()+" 's request for " + request.getMoney());
return;
} else {
if(this.getNextchain()!=null){
this.getNextchain().doRequest(request);
}
}
}
}

[/java]

总经理类:

[java]

package com.kaisir.designpattern.chain;

import com.kaisir.designpattern.chain.model.Request;

/**
* Created with IntelliJ IDEA.
* User: Kaisir
* Date: 13-3-23
* Time: 下午2:35
* To change this template use File | Settings | File Templates.
*/
public class GeneralManager extends Manager {          //总经理

@Override
public void doRequest(Request request) {
if (request.getMoney() < 2000) {
System.out.println("GeneralManager has accepted "+request.getName()+" 's request for " + request.getMoney());
return;
} else {
if (this.getNextchain() != null) {      //若额度大于当前职位所能批复额度,继续传递请求。
this.getNextchain().doRequest(request);
}
}
}
}

[/java]

董事长类:

[java]

package com.kaisir.designpattern.chain;

import com.kaisir.designpattern.chain.model.Request;

/**
* Created with IntelliJ IDEA.
* User: Kaisir
* Date: 13-3-23
* Time: 下午2:36
* To change this template use File | Settings | File Templates.
*/
public class BoardChairman extends Manager {

@Override
public void doRequest(Request request) {
if(request.getMoney()<5000){
System.out.println("BoardChairman has accepted "+request.getName()+" 's request for " + request.getMoney());
return;
}
if(this.getNextchain()!=null){
this.getNextchain().doRequest(request);
}
}
}

[/java]

请求实体:

[java]
package com.kaisir.designpattern.chain.model;

/**
* Created with IntelliJ IDEA.
* User: Kaisir
* Date: 13-3-23
* Time: 下午2:38
* To change this template use File | Settings | File Templates.
*/
public class Request {
private String name;
private float money;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public float getMoney() {
return money;
}

public void setMoney(float money) {
this.money = money;
}
}

[/java]

客户端调用主程序:

[java]
package com.kaisir.designpattern.chain;

import com.kaisir.designpattern.chain.model.Request;

/**
* Created with IntelliJ IDEA.
* User: Kaisir
* Date: 13-3-23
* Time: 下午2:53
* To change this template use File | Settings | File Templates.
*/
public class ChainMain {
public static void main(String[] args){
//初始化
DepartmentManager departmentManager=new DepartmentManager();
GeneralManager generalManager=new GeneralManager();
BoardChairman boardChairman=new BoardChairman();
//设置职责链
departmentManager.setNextchain(generalManager);
generalManager.setNextchain(boardChairman);
//初始化请求1
Request request1=new Request();
request1.setName("Kaisir");
request1.setMoney(3000);
//将请求提交给直接上级,部门经理
departmentManager.doRequest(request1);
//初始化请求2
Request request2=new Request();
request2.setName("Zhang");
request2.setMoney(500);
//将请求提交给直接上级,部门经理
departmentManager.doRequest(request2);
//初始化请求3
Request request3=new Request();
request3.setName("Liu");
request3.setMoney(1500);
//将请求提交给直接上级,部门经理
departmentManager.doRequest(request3);
//初始化请求4
Request request4=new Request();
request4.setName("X-Man");
request4.setMoney(10000);
//将请求提交给直接上级,部门经理
departmentManager.doRequest(request4);
}
}

[/java]

执行结果:

[bash]

BoardChairman has accepted Kaisir 's request for 3000.0
Department Manager has accepted Zhang 's request for 500.0
GeneralManager has accepted Liu 's request for 1500.0

[/bash]

大家不知道有没有注意实际申请人有4人,但是结果回显只有3人,这里要请大家注意的是,一定要记得请求一定要被职责链上的对象所捕获,若超过范围,没有对象能够捕获,请求就会丢掉。


6 条评论

  1. cheap jersey说道:

    我想说 博主你写的是PHP么。。为啥我看不懂

  2. Jclyn说道:

    😛 翻博客又看到你了
    你还是写我看不懂的
    但我还是会想你的!!!

  3. 啊呜堂说道:

    😮
    您好,我是通过百度搜索看到您的网页的,我不是小广告来的。
    有件事情想问您能否帮个忙,如果您有时间可否加我的QQ 37598788或者新浪微博啊呜堂?
    期待您的回复。

发表评论

(必填)

(必填)

(以便回访)