职责链模式

很多应用场景里,完成某个请求可能需要一个团体或组织中的一个或多个个体。

比如我们公司请假流程,有审批权限的职位有三个:2天以内项目经理批准,3-5天部门经理批准,5天以上总经理批准,这时候你就要自己确定请假天数需要找谁审批,然后自己拿着请假条去找各个可能都没见过的领导签字,签字前还要介绍一下你是哪个部门的,好蛋疼。

再说一下现在的老大难,看病,其实治病的一个机构体系是很庞大的。前阵子有点发烧,去社区门诊看病,说发烧治不了,让我去二级大医院看,没办法自己去药店买了点药扛过去了。根据病情不同选择医疗水平不同的医院治疗,这无可厚非。但是现在一个发烧就要在大医院挂号验血等花上个七八百,事后也是给你开一大袋子包装精美的口服药,个人觉得好扯淡。

再说前阵子的佳话:我爸是**,充分证明了不作就不会死,坑爹还招人恨,他爸要是玄德,这哥们估计会被摔成泥。这里也有一个执法体系对交通事故进行处理,小磕小碰找学校保安协调私了就行了;事情严重了就找交警;到了天怒人怨并且有后台的主,那就去法院吧,法院会体面的给你一锤子。

上面的例子可以看出来,应用场景中发出的请求会根据一些判断水准被体系中的一个或多个个体处理,以上面交通事故为例,正常情况下出了交通事故我们先去找协警(保安大哥)处理,协警大哥来了一看,卧槽死人了,我管不了;然后咱们再去找交警,交警大哥来了一看,卧槽他爸是**,我管不了,我劝你还是忍了吧;然后咱们只能向法院提起诉讼了。代码如下:

 

//事故

public class Accident {

public int damage;//以千为单位

public boolean lossLife;//是否有生命损失

public Accident()

{

damage = 0;

lossLife = false;

}

}

 

//负责人保安

public class Security {

public boolean dealAccident(Accident acc)

{

if (acc.lossLife)

{

System.out.printf("死人了,这事我管不了,你赶紧报警去吧!\n");

return false;

}

if(acc.damage >=10)

{

System.out.printf("呦呦呦,怎么撞得这么惨,这要赔好多钱吧,我要下班了,回聊!\n");

return false;

}

 

System.out.printf("别担心,有保安大哥在,这事给你安排的踏踏实实的,去给我买包烟!\n");

return true;

}

}

 

//负责人交警

public class Police {

public boolean dealAccident(Accident acc)

{

if (acc.lossLife)

{

System.out.printf("出人命了,这事我们管不了,你们去打官司吧!\n");

return false;

}

if(acc.damage >=100 || acc.damage <10)

{

System.out.printf("这个经济损失不在我们受理范围内,什么?找谁处理,我们哪里知道!\n");

return false;

}

 

System.out.printf("我们已经出警,请稍等5个小时,我们马上就到!\n");

return true;

}

}

 

//负责人法院

public class Court {

public boolean dealAccident(Accident acc)

{

if (acc.lossLife)

{

System.out.printf("人命关天,不管你爸是谁,你丫今天必须交待在这!\n");

return true;

}

if(acc.damage <100)

{

System.out.printf("这点破事儿也来告状,我们建议你们庭下调节!\n");

return false;

}

 

System.out.printf("赔钱,不赔钱就把你的房子拍卖了!\n");

return true;

}

}

 

//应用场景

public class Client {

public static void main(String[] args) {

// TODO Auto-generated method stub

Accident acc = new Accident();

acc.damage = 60;

acc.lossLife = false;

Security sec = new Security();

if(sec.dealAccident(acc))return;

Police pol = new Police();

if(pol.dealAccident(acc))return;

Court cou = new Court();

if(cou.dealAccident(acc))return;

}

}

综上可知,如果受害人想要维护自己的权益,他需要遍历有可能处理此事的所有权利机构,幸运的话,你找第一个机构就找对了,不幸的话,你要一直找到最后一个机构,这样受害人就需要熟悉所有的权力机构,如果某一个机构发生变化了,那么应用场景也要跟着修改。如果处理请求的类不做条件判断,那么应用场景还要做条件判断;

无论怎么设计,应用场景都会与所有请求处理类相耦合,那么在这种情况下,我们有没有方法进一步实现请求的发送者和请求的所有接收者的解耦呢,我们观察到,接收请求的所有类组成了一个团体,他们对外表现的统一特征都是处理某个或某些请求,我们可以理解他们为一个组织,并很多情况下组织里的个体对于某些请求的处理有相似的判断条件,这个时候这些请求处理类对于请求发起者就应该以组织的形式存在,也就是说,请求发起者不用找具体的处理类,他只需要对这个组织发出请求,组织内部如何协调指定具体的处理类,如何进行具体的处理,对于这些,请求者都不用管,他只等待结果就好了,也可以把组织理解为一个黑盒,请求者输入请求,组织返回结果,这样对于组织内部的请求处理类的增加/删除/修改都不会影响到应用场景。

我们可以把这些请求处理者以链的形式串起来,请求在这些处理者间链式传递,直到其被接收并处理。这就是我们说的职责链模式。

职责链模式:将处理同一类请求的对象组成链,并且让请求在链上传递,使得每个对象都有机会处理请求,直到有一个对象对其进行处理。从而避免请求发送者和请求接收者间的耦合关系。

 

一、特征

1、同一类请求:这是这些对象的共性,也是他们可以连成线组成黑盒的基础,这说明这些对象在处理同一请求的时候在很大程度上接口的调用形式是一样的。

2、链:这里的线不拘于一条直线,可能会是树,反正是链式的,让所有对象都有机会处理请求即可。具体展现形式要根据实际场景处理。并且链是任意组合的,比如一个处理对象过气了,那我们可以通过简单的代码完成链的重组而不影响应用场景的使用。

3、传递:请求在这个链里面注重的是传递,而不是从哪里传递,选择合适的处理器起点往往会增加请求处理效率,比如我们上面的交通事故,我们发现事故中出现人命,那我们可以直接将请求发送给警察就好了,因为即使你找保安他们以实报警。

 

二、作用:

有些应用场景里处理同一类请求的对象有多个,具体处理者需要根据某些判断条件从这些对象中筛选,这时候为了减小请求发送者和这些处理对象的耦合,我们将这些对象链式封装。

 

三、实现:

 

 

我们来看看上面的交通事故怎么实现:

 

//请求处理对象虚基类

abstract public class Handler {

abstract public void setSuccessor(Handler succ);

abstract public boolean dealAccident(Accident acc);

}

 

//实际处理对象-保安

public class testSecurity extends Handler{

private Handler successor;

public testSecurity()

{

successor = null;

}

@Override

public void setSuccessor(Handler succ) {

// TODO Auto-generated method stub

successor = succ;

}

@Override

public boolean dealAccident(Accident acc) {

// TODO Auto-generated method stub

if (acc.lossLife || acc.damage >=10)

{

if(successor != null)

{

return successor.dealAccident(acc);

}

else

{

return false;

}

}

System.out.printf("别担心,有保安大哥在,这事给你安排的踏踏实实的,去给我买包烟!\n");

return true;

}

}

 

 

//实际处理对象-交警

public class testPolice extends Handler{

private Handler successor;

public testPolice()

{

successor = null;

}

 

@Override

public void setSuccessor(Handler succ) {

// TODO Auto-generated method stub

successor = succ;

}

 

@Override

public boolean dealAccident(Accident acc) {

// TODO Auto-generated method stub

if (acc.lossLife || acc.damage >=100 || acc.damage <10)

{

if(successor != null)

{

return successor.dealAccident(acc);

}

else

{

return false;

}

}

System.out.printf("我们已经出警,请稍等5个小时,我们马上就到!\n");

return true;

}

}

 

 

//实际处理对象-法院

public class testCourt extends Handler{

private Handler successor;

 

public testCourt()

{

successor = null;

}

 

@Override

public void setSuccessor(Handler succ) {

// TODO Auto-generated method stub

successor = succ;

 

}

 

@Override

public boolean dealAccident(Accident acc) {

// TODO Auto-generated method stub

if (acc.lossLife)

{

System.out.printf("人命关天,不管你爸是谁,你丫今天必须交待在这!\n");

return true;

}

else if (acc.damage <100)

{

if(successor != null)

{

return successor.dealAccident(acc);

}

else

{

return false;

}

}

else

{

System.out.printf("赔钱,不赔钱就把你的房子拍卖了!\n");

}

 

return true;

 

}

}

 

 

//应用场景

public class Client {

 

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

Accident acc = new Accident();

acc.damage = 60;

acc.lossLife = true;

Handler security = new testSecurity();

Handler police = new testPolice();

security.setSuccessor(police);

police.setSuccessor(new testCourt());

security.dealAccident(acc);

}

 

}

 

 

在实际的应用场景中,其他模块只需要传给应用场景一个职责链句柄它就可以自由发挥了。这正符合了咱们所说的迪米特法则。不和陌生人说话。

做qt界面开发的人或多或少的都了解一些事件处理机制吧,事件在控件与父控件间链式传递,如果子控件不处理此事件,事件会上传到其父控件上,依此类推,知道有一个控件受理此事件,事件处理才会结束。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值