什么是责任链模式
在生活中,责任链模式的实现比较多,比如说“击鼓传花”这个游戏,大家包围成一个圈,接连的传递这个花球。另外有个人在圈外负责击鼓时间到了花球就到了某个人的手里,这个人收到花球(请求),进而给大家唱歌或者别的什么的(响应)
再比如说去买房,首先来了一个普通购房者,和销售说,我全款买一套房,给我打个九折吧。销售知道九折在自己所在的权限范围内,便给买房子的人打了一个九折的优惠。然后,又来了一个土豪,想买三套房,想让销售打八折,但是销售的权限太小,八折这个请求需要继续向上提交,于是销售便告诉了他的上级主管,主管知道八折在他的权限之内可以打折,于是便给土豪打了八折的优惠。
经典代码演示
/**
*价格处理的抽象类,用来处理客户端传递过来的申请
*服务端
*/
public abstract class PriceHandler{
//指向自身类型的引用,直接后继,用于传递请求,链表的形式
protected PriceHandler successor;
public void setPriceHandler(PriceHandler successor){
this.successor = successor;
}
//处理折扣申请
public abstract void processDiscount(float discount);
//工厂方法,创建各个销售层
public static PriceHandler createPriceHandler(){
PriceHandler sales = new Sales();
PriceHandler man = new Manager();
PriceHandler ceo = new CEO();
sales.setSuccessor(man);
man.setSuccessor(ceo);
return sales;
}
}
/**
*销售,批准5%的折扣
*/
public class Sales extends PriceHandler{
public void processDiscount(float discount){
if(discount <= 0.05){
System.out.format("%s批准了折扣:%.2f%n",this.getClass().getName(),discount);
}else{
successor.processDiscount(discount);
}
}
}
/**
*主管批准10%的折扣
*/
public class Manager extends PriceHandler {
public void processDiscount(float discount) {
if(discount <=0.10){
System.out.format("%s批准了折扣:%.2f%n",this.getClass().getName(),discount);
}else{
successor.processDiscount(discount);
}
}
}
/**
*CEO批准20%的折扣
*/
public class CEO extends PriceHandler {
public void processDiscount(float discount) {
if(discount <= 0.20){
System.out.format("%s批准了折扣:%.2f%n",this.getClass().getName(),discount);
}else{
System.out.format("%s拒绝了折扣:%.2f%n",this.getClass().getName(),discount);
}
}
}
/**
*客户端,发出一个请求
*/
public class Customer{
private PriceHandler priceHandler;
public void setPriceHandler(PriceHandler priceHandler) {
this.priceHandler = priceHandler;
}
public static void main(String[] args) {
Customer customer = new Customer();
customer.setPriceHandler(PriceHandler.createPriceHandler());
//采用随机数,确定折扣值
Random rand = new Random();
for(int i=1;i<=50;i++){
System.out.print(i+":");
customer.requestDiscount(rand.nextFloat());
}
}
}
按理说,PriceHandler是一个抽象类,并且Java类遵循单一职责原则,对于PriceHandler中有一个工厂的方法,这应该是不正确的,如果没人告诉,没有人会知道PriceHandler除了是负责为子类提供方法外,还负责工厂的职责,来维护这些子类,所以,我们应该把工厂方法单独提取出来,也更便于维护。
//价格处理的抽象类,用来处理客户端传递过来的申请
public abstract class PriceHandler{
//指向自身类型的引用,直接后继,用于传递请求
protected PriceHandler successor;
public void setPriceHandler(PriceHandler successor){
this.successor = successor;
}
//处理折扣申请
public abstract void processDiscount(float discount);
}
// 销售,批准5%的折扣,Manager和CEO依旧是像之前那样写
public class Sales extends PriceHandler{
public void processDiscount(float discount){
if(discount <= 0.05){
System.out.format("%s批准了折扣:%.2f%n",this.getClass().getName(),discount);
}else{
successor.processDiscount(discount);
}
}
}
//工厂类,负责维护销售层
public class PriceHandlerFactory{
public static PriceHandler createPriceHandler(){
PriceHandler sales = new Sales();
PriceHandler man = new Manager();
PriceHandler ceo = new CEO();
sales.setPriceHandler(man);
man.setPriceHandler(ceo);
return sales;
}
}
//客户端
public class Customer{
private PriceHandler priceHandler;
public void setPriceHandler(PriceHandler priceHandler){
this.priceHandler = priceHandler;
}
public void requestDiscount(float discount){
priceHandler.processDiscount(discount);
}
//主方法
public static void main(String[] args){
Customer customer = new Customer();
customer.setPriceHandler(PriceHandlerFactory.createPriceHandler());
Random rand = new Random();
for(int i=1;i<=50;i++){
System.out.print(i+" ");
customer.requestDiscount(rand.nextFloat());
}
}
}
结构图
总结
责任链模式用起来感觉还比较方便,将工作类可以串联起来,对于现实事务比较方便抽象。
但是对于一旦PriceHandler继承的子类越来越多,就会引起性能的下降,而且,可能对于实例化的对象有很多只是保存在内存中,但可能并不会使用到,比较浪费内存。