概述
在日常生活中,我们如果仔细观察的话,很多事情都蕴含着责任链模式的思想;比如某个人去售楼处买房,对销售人员提出打折的要求,如果折扣比较
小,销售人员有权给予该购买者提出的折扣优惠,就可以直接答应该请求;如果折扣过大,销售人员无权答应,则会想他的上司——销售组长询问,
如果销售组长有权答应该折扣,则直接回复可以,并将房子售卖给客户;以此类推,直至该折扣请求被处理,客户得到相应的答复,该事件结束。
再比如,我们曾经玩过的抛手绢、击鼓传花等游戏,都有责任链模式的影子;总的来说,责任链模式就是:将接收者对象连城一条链,将对应的请求
在该链上进行传递,直至有接收者对象处理了该请求;这种通过允许更多接收者对象有机会对请求进行处理,来避免请求者和接收者之间的耦合;
其中,责任链模式中的“责任链”源于在链上的每个处理者都有责任去处理在链上传递的请求,同时,处理者对应不同等级的请求,相应地有处理请求
的权限;
另外,在上面的例子中,购房者不需要知道谁处理了他的折扣请求,击鼓传花中,击鼓者,也不需要知道是谁拿到花并进行节目表演,这就解释了
上面说的请求者和接收处理者之间的去耦合是怎么一回事。
下面将以生活中公司中职员请假的流程作为示例,采用责任链模式进行代码的设计,通过直观的讲解来阐述责任链模式的设计思想;
package com.pattern.handler;
/**
* 假期申请接收者对应的抽象类,负责处理工作人员的假期申请
*/
public abstract class LeaveHandler
{
/**
* 直接后继管理人员,用于传递请求
*/
protected LeaveHandler successor;
public void setSuccessor(LeaveHandler successor)
{
this.successor = successor;
}
/**
* 处理假期申请
*/
public abstract void processLeave(int days);
}
package com.pattern.handler;
/**
* 组长类, 可以批准2天以内的假期申请
*/
public class GroupLeader extends LeaveHandler
{
@Override
public void processLeave(int days)
{
if(days<=2)
{
System.out.println(this.getClass().getName()+"批准了"+days+"天假");
}
else
{
successor.processLeave(days);
}
}
}
package com.pattern.handler;
/**
* 副主任类, 可以批准3天以内的假期申请
*/
public class ViceManager extends LeaveHandler
{
@Override
public void processLeave(int days)
{
if(days<=3)
{
System.out.println(this.getClass().getName()+"批准了"+days+"天假");
}
else
{
successor.processLeave(days);
}
}
}
package com.pattern.handler;
/**
* 主任类, 可以批准5天以内的假期申请
*/
public class Manager extends LeaveHandler {
@Override
public void processLeave(int days)
{
if(days<=5)
{
System.out.println(this.getClass().getName()+"批准了"+days+"天假");
}
else
{
successor.processLeave(days);
}
}
}
package com.pattern.handler;
/**
* 总经理类,可以批准10天以内的假期申请
* 假期超过10天, 就拒绝申请
*/
public class GeneralManager extends LeaveHandler {
@Override
public void processLeave(int days)
{
if(days<=10)
{
System.out.println(this.getClass().getName()+"批准了"+days+"天假");
}
else
{
System.out.println(this.getClass().getName()+"不批准"+days+"天假");
}
}
}
package com.pattern.handler;
public class LeaveHandlerFactory {
/**
* 创建LeaveHandler的工厂方法
*/
public static LeaveHandler createPriceHandler()
{
LeaveHandler gl = new GroupLeader();
LeaveHandler vm = new ViceManager();
LeaveHandler m = new Manager();
LeaveHandler gm = new GeneralManager();
gl.setSuccessor(vm);
vm.setSuccessor(m);
m.setSuccessor(gm);
return gl;
}
}
package com.pattern;
import java.util.Random;
import com.pattern.handler.LeaveHandler;
import com.pattern.handler.LeaveHandlerFactory;
/**
* 工作人员,申请假期
*/
public class Client {
private LeaveHandler leaveHandler;
public void setLeaveHandler(LeaveHandler leaveHandler)
{
this.LeaveHandler = leaveHandler;
}
public void requestLeave(int days)
{
leaveHandler.processLeave(days);
}
public static void main(String[] args)
{
Client client = new Client();
client.setLeaveHandler(LeaveHandlerFactory.
createLeaveHandler());
Random random = new Random();
for(int i=1;i<=100;i++){
System.out.print(i+":");
client.requestLeave(random.nextInt(20));
}
}
}
代码重点分析:
①抽象类LeaveHandler包含一个自身类型的数据域,这个数据域的别名叫做责任链上的后继者,当本类的对象无权处理请求时,就将该请求传递
给该数据域对应的对象进行处理,这一点非常重要,是形成责任链的关键所在!
②抽象类LeaveHandler属于Java中泛指的接口,这里使用抽象类作为接口,体现了面向接口编程的思想,这一点要注意!
③这里将不同类型的处理者的产生交由工厂类LeaveHandlerFactory来完成,体现了面向对象(OO)中类设计的单一职责原则,即对于某一
接口或类,只把该接口或类的相关方法放进该接口或类中。同时,Java的命名规范要求我们设计类或接口时,能够见名知意,每一个类的类名必须
代表着该类的语义!
④通过分析上述代码,可以发现职员类只和import com.pattern.handler.LeaveHandler以及import com.pattern.handler.LeaveHandlerFactory两个类相关联,
并没有和继承于抽象类LeaveHandler的具体类相关联,这就带来了业务变更时,
无需修改接口,只需要增加继承于LeaveHandler的类即可;比如,当公司中等级变化时(对应管理人员的等级有所增加),可以通过再设计一个
对应类,并在工厂类中进行该类对象的获取,并将其嵌入责任链中,即可实现该项目仍可以正常工作,这就体现了设计模式应对不同场景时独具
的优势,体现了项目的可扩展性!
在责任链模式中存在着一些缺点,就本例来说:
①当请假的天数较少,只需要经过一个或者少数的处理者就可以处理该请求,那么这就造成之后的处理者被创建出来,但是并没有参与业务
处理,造成时间和空间上的浪费。
②当多个职员请假时,需要分别创建一组管理人员对象,这就造成了不必要的开销,其实,只需一组管理人员对象即可处理多名职员的请假请求。
责任链模式在Java的前端或者后台开发中也会常常遇到,比如后端开发中遇到的异常处理机制、Java Web中的过滤器链;
前端开发中的JavaScript中的事件触发处理过程,都蕴含了责任链模式的设计思想!
最后
以上就是复杂香氛为你收集整理的Java设计模式(5)之责任链模式学习总结的全部内容,希望文章能够帮你解决Java设计模式(5)之责任链模式学习总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复