0

责任链模式 - mingmingcome

 1 year ago
source link: https://www.cnblogs.com/mingmingcome/p/17233761.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

begin 2021年12月11日20:47:41

责任链模式

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. ——《Design Patterns: Elements of Reusable Object-Oriented Software》

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将接收对象连城一条链,并沿着链传递该请求,直到有一个对象处理它为止。 ——《设计模式:可复用面向对象软件的基础》

责任链模式是一种行为型设计模式。

在以下场景下使用责任链模式:

  • 有多个对象处理一个请求时,且处理者不知道处理优先级。
  • 你想让多个处理者处理一个请求,不需要知道具体处理者。
  • 处理请求的对象集合应该是自动确定的。

总的来说,就是处理请求的处理者有多个,但是客户端只知道其中一个,其他都是主动排好队,等着处理请求的。

责任链结构图:

责任链结构图

客户端(Client):

  • 初始化请求给责任链上的一个具体处理者

抽象处理者(Handler):

  • 定义一个处理请求的接口
  • 设置下一位处理者的引用

具体处理者(Handler):

  • 处理它负责的请求
  • 如果具体处理者可以处理请求,就处理;否则,将请求交给它的继承者

请求(Request):

  • 封装了需要处理的信息,传递给处理者进行处理。
// 抽象处理者类
abstract class Handler {
    protected Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public abstract void handleRequest(Request request);
}

// 具体处理者类A
class HandlerA extends Handler {
    public void handleRequest(Request request) {
        if (request.getType() == RequestType.TYPE_A) {
            // 处理请求
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

// 具体处理者类B
class HandlerB extends Handler {
    public void handleRequest(Request request) {
        if (request.getType() == RequestType.TYPE_B) {
            // 处理请求
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

// 请求类
class Request {
    private RequestType type;

    public Request(RequestType type) {
        this.type = type;
    }

    public RequestType getType() {
        return type;
    }
}

// 请求类型枚举类
enum RequestType {
    TYPE_A, TYPE_B
}

// 使用示例
public class Client {
    public static void main(String[] args) {
        Handler handlerA = new HandlerA();
        Handler handlerB = new HandlerB();
        handlerA.setSuccessor(handlerB);

        Request request1 = new Request(RequestType.TYPE_A);
        handlerA.handleRequest(request1);

        Request request2 = new Request(RequestType.TYPE_B);
        handlerA.handleRequest(request2);
    }
}

故事版代码示例

产房内哇的一声啼哭,你已经降临这个世界。

你慢慢长大,学习,工作,结婚生子。

爸妈永远是你的支持。

public interface Support {
    void setSuccessor(Support successor);
    void handle(You you);
}

public class MaMa implements Support {
    private String name = "妈妈";
    private Support successor;
    @Override
    public void setSuccessor(Support successor) {
        this.successor = successor;
    }

    @Override
    public void handle(You you) {
        if (you.getObtainType() == ObtainType.NAME) {
            System.out.println(name + ":怀孕了,起个好听的名字");
            successor.handle(you);
        } else if (you.getObtainType() == ObtainType.BORN) {
            System.out.println(name + ":十月怀胎,你出生了");
            successor.handle(you);
        } else if (you.getObtainType() == ObtainType.EDUCATION) {
            System.out.println(name + ":十六年努力工作,提供给你最好的教育");
            successor.handle(you);
        } else if (you.getObtainType() == ObtainType.WORK) {
            System.out.println(name + ":给你鼓励");
            successor.handle(you);
        } else if (you.getObtainType() == ObtainType.MARRIAGE) {
            System.out.println(name + ":倾尽所有买房买车");
            successor.handle(you);
        }
    }
}

public class BaBa implements Support{
    private String name = "爸爸";
    private Support successor;
    @Override
    public void setSuccessor(Support successor) {
        this.successor = successor;
    }

    @Override
    public void handle(You you) {
        if (you.getObtainType() == ObtainType.NAME) {
            System.out.println(name + ":让岳父起个好听的名字");
            successor.handle(you);
        } else if (you.getObtainType() == ObtainType.BORN) {
            System.out.println(name + ":高兴");
            successor.handle(you);
        } else if (you.getObtainType() == ObtainType.EDUCATION) {
            System.out.println(name + ":十六年和妈妈一起努力工作,提供给你最好的教育");
            successor.handle(you);
        } else if (you.getObtainType() == ObtainType.WORK) {
            System.out.println(name + ":给你指导");
            successor.handle(you);
        } else if (you.getObtainType() == ObtainType.MARRIAGE) {
            System.out.println(name + ":和妈妈一起倾尽所有买房买车");
            successor.handle(you);
        }
    }
}

public class WaiGong implements Support {
    private String name = "外公";
    private Support successor;
    @Override
    public void setSuccessor(Support successor) {
        this.successor = successor;
    }

    @Override
    public void handle(You you) {
        if (you.getObtainType() == ObtainType.NAME) {
            System.out.println(name + ":名叫晓月");
        } else if (you.getObtainType() == ObtainType.BORN) {
            System.out.println(name + ":你们多了一份责任");
        } else if (you.getObtainType() == ObtainType.EDUCATION) {
            System.out.println(name + ":暑假的大热天的扇子,冬天热乎的番薯");
        } else if (you.getObtainType() == ObtainType.WORK) {
            System.out.println(name + ":你很努力,也很棒");
        } else if (you.getObtainType() == ObtainType.MARRIAGE) {
            System.out.println(name + ":开心看到你结婚");
        }
    }
}

public class Family {
    public static void main(String[] args) {
        // 爸爸
        BaBa baBa = new BaBa();
        // 妈妈
        MaMa maMa = new MaMa();
        // 外公
        WaiGong waiGong = new WaiGong();

        // 结婚,爸爸成了妈妈的支持
        maMa.setSuccessor(baBa);
        // 外公对爸爸说,我们是一家人,我可以成为你的支持
        baBa.setSuccessor(waiGong);
        // 妈妈怀孕了
        You you = new You();
        you.setAge(-1);
        // 你一生的支持,103岁die
        while(you.getAge() < 103) {
            // 你主观或者客观提出了请求
            produceRequest(you);
            // 家人支持处理你的请求
            handleRequest(you, maMa);
            // 下一重要阶段
            setNextAge(you);
        }

    }

    private static void setNextAge(You you) {
        if (you.getAge() == -1) {
            you.setAge(0);
        } else if (you.getAge() == 0) {
            you.setAge(3);
        } else if (you.getAge() >= 3 && you.getAge() < 22) {
            you.setAge(22);
        } else if (you.getAge() >= 22 && you.getAge() < 24) {
            you.setAge(24);
        } else if (you.getAge() == 24) {
            you.setAge(103);
        }
    }

    private static void handleRequest(You you, MaMa maMa) {
        maMa.handle(you);
    }

    private static void produceRequest(You you) {
        if (you.getAge() == -1) {
            you.setObtainType(ObtainType.NAME);
        } else if (you.getAge() == 0) {
            you.setObtainType(ObtainType.BORN);
        } else if (you.getAge() >= 3 && you.getAge() < 22) {
            you.setObtainType(ObtainType.EDUCATION);
        } else if (you.getAge() >= 22 && you.getAge() < 24) {
            you.setObtainType(ObtainType.WORK);
        } else if (you.getAge() == 24) {
            you.setObtainType(ObtainType.MARRIAGE);
        }
    }
}

代码示例结果:

责任链模式示例结果图

责任链模式的优点在于它可以将请求的处理分散到多个对象中,降低了对象之间的耦合度。同时,责任链模式也比较灵活,可以动态地组织处理者链,以满足不同的需求。

但是责任链模式也有一些缺点。首先,由于每个处理者都要处理请求,因此处理者链过长或者处理者数量过多可能会影响性能。其次,如果处理者链没有被正确组织,可能会导致请求无法得到处理或者处理不当的情况发生。

当你需要多个处理者处理一个请求,并想任意组合处理者时,可以使用责任链模式。该模式具有降低耦合,以及灵活组织处理者的优点。

2023年03月19日17:36:53


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK