您的位置:首页 > 编程语言 > Java开发

Java设计模式——责任链模式

2016-09-12 09:30 423 查看
定义

责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。

生活实例

请假对大家都不陌生,你要请假,无论是请几天,总有一个人要处理你的请假申请。请假1天,可能小组长就直接批了,而请假一个月,小组长可能就说,这个事我管不了,但是我可以向经理请示一下,经理回复说,这个我去找副总说一下,副总最终回复,你走吧,走了就不要再回来了,最终你的申请得到了审批。

另一个例子就是DNS查询,客户DNS服务器发起一个DNS查询总会收到一个响应,无论是正确的还是错误的,也不管响应是由哪一级DNS服务器返回的,可能是从某服务器的缓存中就拿到了你想要的响应,也有可能是从本地拿到的缓存。

 

责任链模式中的角色

抽象处理者角色:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。

具体处理者角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

简单实现

打折申请,下面的例子是打折申请的简单实现。你要去买辆车,去了4S店。你可能要求打八折,亦或是五折,这样销售人员可能处理不了你这样的请求,转而向上申请处理,或者是直接说你是来找茬的吗?

代码

 

/**
 * 价格处理人,负责处理客户折扣申请
 * @author
Goser    (mailto:goskalrie@163.com)
 * @Since 2016年9月9日
 */
public
abstract class
PriceHandler {
 
    /**直接后继,用于传递请求 */
    protected PriceHandler
successor;
 
    protected
void
setSuccessor(PriceHandler successor) {
        this.successor = successor;
    }
   
    public
abstract void
processDiscount(float discount);
}

 

public
class
PriceHandlerFactory {
    /**  创建PriceHandler的工厂方法 */
    public
static
PriceHandler createPriceHandler() {
        PriceHandler sales = new Sales();
        PriceHandler manager = new Manager();
        PriceHandler ceo = new CEO();
        sales.setSuccessor(manager);
        manager.setSuccessor(ceo);
        return sales;
    }
}

 

/** 销售,可以批准5%以内的折扣 ,若大于50%拒绝服务*/
public
class
Sales extends PriceHandler {
    @Override
    public
void
processDiscount(float discount) {
        if(discount <= 0.05){
            System.out.format("%s批准了折扣:%.2f%n",this.getClass().getName(),discount);
        }else
if
(discount > 0.5){
            System.err.format("拒绝折扣%.2f:你是来找茬的么?%n",discount);
        }else{
            successor.processDiscount(discount);
        }
    }
}

/** 经理,可以批准20%以内的折扣 */
public
class
Manager extends PriceHandler {
 
    @Override
    public
void
processDiscount(float discount) {
        if(discount <= 0.2){
            System.out.format("%s批准了折扣:%.2f%n",this.getClass().getName(),discount);
        }else{
            successor.processDiscount(discount);
        }
    }
}

 

/**  CEO,可以批准50%以内的折扣,或是拒绝 */
public
class
CEO extends PriceHandler {
    @Override
    public
void
processDiscount(float discount) {
        if(discount <= 0.5){
            System.out.format("%s批准了折扣:%.2f%n",this.getClass().getName(),discount);
        }else{
            System.err.format("%s拒绝了折扣:%.2f%n",this.getClass().getName(),discount);
        }
    }
}

 

/** 客户,要申请折扣 */
public
class
Customer {
 
    private PriceHandler
priceHandler;
   
    public
void
setPriceHandler(PriceHandlerpriceHandler) {
        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 discount = new Random();
        for(int i=1; i<=100;i++){
            System.out.print(i+":");
            customer.requestDiscount(discount.nextFloat());
        }
    }
}

 

链的创建是在工厂方法中完成的,若此时中间多了一层,则只需要新增一个类,并在工厂方法中增加一层即可。

所谓的链不一定是一条直线,可能是树状的,比如DOM树,DOM中的事件冒泡流也是应用的责任链模式。更典型的应用是Filter。链的形状由业务逻辑具体决定。

总结

优点

实现了请求者与处理者代码分离:发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。提高系统的灵活性和可扩展行。

缺点

最终完成请求的类只有一个,会造成资源浪费。如果很长的一条链,假如是100个,而最后一个完成了请求,那么前面的99个对象就是垃圾对象,原先的AWT使用的是链模式现在转而选择使用观察者模式,大部分的原因就是AWT中链的结构可能会很长,影响整体性能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: