说说Chain of Responsibility模式理解

简介: 说说Chain of Responsibility模式理解

责任链模式

我们首先看看什么是推卸责任。假设现在我们要去公司领取资料。首先我们向公司前台打听要去哪里领取资料,她告诉我们应该去“营业窗口”。然后等我们到了“营业窗口”后,又被告知应该去“售后部门”。等我们好不容易赶到了“售后部门”,又被告知应该去“资料中心”,因此最后我们又不得不赶往“资料中心"。像这样,在找到合适的办事人之前,我们被不断地踢给一个又一个人,这就是“推卸责任”。

“推卸责任”听起来有些贬义的意思,但是有时候也确实存在需要“推卸责任”的情况。例如,当外部请求程序进行某个处理,但程序暂时无法直接决定由哪个对象负责处理时,就需要推卸责任。这种情况下,我们可以考虑将多个对象组成一条职责链,然后按照它们在职责链上的顺序一个一个地找出到底应该谁来负责处理。

这种模式被称为Chain of Responsibility模式。

使用Chain of Responsibility模式可以弱化“请求方”和“处理方”之间的关联关系,让双方各自都成为可独立复用的组件。此外,程序还可以应对其他需求,如根据情况不同,负责处理的对象也会发生变化的这种需求。

当一个人被要求做什么事情时,如果他可以做就自己做,如果不能做就将“要求”转给另外一个人。下一个人如果可以自己处理,就自己做;如果也不能自己处理,就再转给另外一个人……这就是Chain of Responsibility模式。

事例程序

类一览表

名字 说明
Trouble 表示发生问题的类
Support 用来决解决问题的抽象类
NoSupport 解决问题的具体类
LimitSupport 解决问题的具体类
OddSupport 解决问题的具体类
SpecialSupport 解决问题的具体类
Main 测试

类图

image.png

代码

Trouble

  • 发生问题的类,number表示问题的编号(解决问题通过问题编号解决)
  • getNumber():的到问题编号
public class Trouble {
    private int number;
    public Trouble(int number) {
        this.number = number;
    }
    public int getNumber() {
        return number;
    }
    @Override
    public String toString() {
        return "Trouble{" +
                "number=" + number +
                '}';
    }
}

Support

  • 解决问题的抽象类
  • next表示下一个接手问题的对象,通过setNext指定
  • resolve方法是需要子类去实现的抽象方法。如果resolve返回true,则表示问题已经被处理,如果返回false则表示问题还没有被处理(即需要被推卸给下一个对象)。
  • (调用抽象方法resolve,模板模式)如果resolve方法返回false,则support方法会将问题转交给下一个对象。如果已经到达职责链中的最后一个对象,则表示没有人处理问题,将会显示出处理失败的相关信息。
public abstract class Support {
    private String name;
    private Support next;
    public Support(String name) {
        this.name = name;
    }
    public Support setNext(Support next) {
        this.next = next;
        return next;
    }
    public final void support(Trouble trouble) {
        if (resolve(trouble)){
            done(trouble);
        }else if(next!=null){
            next.support(trouble);
        }else{
            fail(trouble);
        }
    }
    @Override
    public String toString() {
        return "Support{" +
                "name='" + name + ''' +
                '}';
    }
    protected abstract boolean resolve(Trouble trouble);
    protected void done(Trouble trouble) {
        System.out.println(trouble + "is resolve by" + this);
    }
    protected void fail(Trouble trouble) {
        System.out.println(trouble + "can't  be resolved");
    }
}

Nosupport

  • Support的子类
  • resolve返回false表示无法解决
public class NoSupport extends Support{
    public NoSupport(String name) {
        super(name);
    }
    @Override
    protected boolean resolve(Trouble trouble) {
        return false;
    }
}

LimitSupport

  • 编号小于limit表示解决成功,可接具体的处理逻辑
public class LimitSupport extends Support {
    private int limit;
    public LimitSupport(String name, int limit) {
        super(name);
        this.limit = limit;
    }
    @Override
    protected boolean resolve(Trouble trouble) {
        if (trouble.getNumber() < limit) {
            //具体的处理逻辑
            return true;
        }
        return false;
    }
}

OldSupport

  • 解决编号位奇数的问题
public class OldSupport extends Support {
    public OldSupport(String name) {
        super(name);
    }
    @Override
    protected boolean resolve(Trouble trouble) {
        if (trouble.getNumber() % 2 == 1) {
            return true;
        }
        return false;
    }
}

SpecialSupport

  • 解决指定编号的问题
public class SpecialSupport extends Support {
    private int number;
    public SpecialSupport(String name, int number) {
        super(name);
        this.number = number;
    }
    @Override
    protected boolean resolve(Trouble trouble) {
        if (trouble.getNumber() == number) {
            return true;
        }
        return false;
    }
}

Main


public class Main {
    public static void main(String[] args) {
        Support alice = new NoSupport("Alice");
        Support bob = new LimitSupport("Bob", 100);
        Support charlie = new SpecialSupport("Charlie", 429);
        Support diana = new LimitSupport("Diana", 200);
        Support elmo = new OldSupport("Elmo");
        Support fred = new LimitSupport("Fred", 300);
        alice.setNext(bob).setNext(charlie).setNext(diana).setNext(elmo).setNext(fred);
        for (int i = 0; i < 500; i++) {
            alice.support(new Trouble(i));
        }
    }
}

result:

Trouble{number=0}is resolve bySupport{name='Bob'}
Trouble{number=1}is resolve bySupport{name='Bob'}
Trouble{number=2}is resolve bySupport{name='Bob'}
Trouble{number=3}is resolve bySupport{name='Bob'}
Trouble{number=4}is resolve bySupport{name='Bob'}
Trouble{number=5}is resolve bySupport{name='Bob'}
............
............
............
Trouble{number=495}is resolve bySupport{name='Elmo'}
Trouble{number=496}can't  be resolved
Trouble{number=497}is resolve bySupport{name='Elmo'}
Trouble{number=498}can't  be resolved
Trouble{number=499}is resolve bySupport{name='Elmo'}

登场角色

image.png

  • Handler(处理者)
    Handler 角色定义了处理请求的接口(API )。Handler 角色知道“下一个处理者”是谁,如果自己无法处理请求,它会将请求转给“下一个处理者”。当然,“下一个处理者”也是Handler角色。在示例程序中,由 support类扮演此角色。负责处理请求的是 support方法。
  • ConcreteHandler(具体的处理者)
    ConcreteVisitor角色是处理请求的具体角色。在示例程序中,由NoSupport、LimitSupport,Oddsupport、 Specialsupport等各个类扮演此角色。
  • Client(请求者)
    发送请求,Main


目录
相关文章
|
7月前
|
设计模式 JavaScript Java
设计模式17 - 责任链模式【Chain of Responsibility Pattern】
设计模式17 - 责任链模式【Chain of Responsibility Pattern】
24 0
|
7月前
|
设计模式 JavaScript Java
设计模式~责任链模式(Chain of Responsibility)-12
目录 (1)优点 (2)缺点 (3)使用场景 (4)注意事项: (5)应用实例: (6)经典案例 代码
38 0
|
9月前
|
设计模式 Java Android开发
责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。在责任链模式中,请求沿着一个链传递,直到有一个对象处理它为止。
44 2
行为型模式 - 责任链模式(Chain of Responsibility Pattern)
行为型模式 - 责任链模式(Chain of Responsibility Pattern)
|
存储 设计模式 Dubbo
行为型-Chain Of Responsibility
职责链模式的原理和实现 职责链模式的英文翻译是 Chain Of Responsibility Design Pattern。在 GoF 的《设计模式》中,它是这么定义的: Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
100 0
行为型-Chain Of Responsibility
|
数据安全/隐私保护 iOS开发
单一职责原则(Single Responsibility Principle,SRP)(中)
单一职责原则(Single Responsibility Principle,SRP)(中)
195 0
单一职责原则(Single Responsibility Principle,SRP)(中)
|
程序员
单一职责原则(Single Responsibility Principle,SRP)(上)
单一职责原则(Single Responsibility Principle,SRP)
120 0
单一职责原则(Single Responsibility Principle,SRP)(上)
|
设计模式 项目管理 数据库
单一职责原则(Single Responsibility Principle,SRP)(下)
单一职责原则(Single Responsibility Principle,SRP)(下)
398 0
单一职责原则(Single Responsibility Principle,SRP)(下)