行为型设计模式:责任链模式、命令模式与迭代器模式

在软件开发中,行为型设计模式关注对象之间的通信,通过定义对象间的交互方式来实现特定的功能。本文将深入解析三种行为型设计模式:责任链模式、命令模式和迭代器模式,并结合实际案例进行分析。

一、责任链模式(Chain of Responsibility Pattern)

(一)定义

责任链模式允许将请求沿着处理者链进行传递,直到某个处理者能够处理该请求为止。这种方式避免了请求发送者与具体处理者之间的耦合关系,使得多个对象都有机会处理请求。

(二)应用场景

  1. Apache Tomcat的编码处理:在处理HTTP请求时,Tomcat通过责任链模式来处理不同的编码问题。

  2. Spring Boot的拦截器和过滤器链:在请求处理过程中,多个拦截器或过滤器按照顺序依次处理请求。

  3. 动态决定请求处理者:当请求的处理者不明确,或者由运行时动态决定时,责任链模式非常适用。

(三)角色

  • Handler(抽象处理者):定义了处理请求的接口,通常包含一个指向下一个处理者的引用。

  • ConcreteHandler(具体处理者):实现抽象处理者接口,具体处理请求。如果无法处理,则将请求传递给下一个处理者。

(四)实现案例

以下是一个风控系统的实现案例:

// 请求类
public class Request {
    private String requestType;
    private int money;

    // 省略set和get方法
}

// 风控管理抽象类
public abstract class RiskControlManager {
    protected String name;
    protected RiskControlManager superior;

    public RiskControlManager(String name) {
        this.name = name;
    }

    public void setSuperior(RiskControlManager superior) {
        this.superior = superior;
    }

    public abstract void handlerRequest(Request request);
}

// 初级风控
public class FirstRiskControlManager extends RiskControlManager {
    public FirstRiskControlManager(String name) {
        super(name);
    }

    @Override
    public void handlerRequest(Request request) {
        if (request.getMoney() <= 1000) {
            System.out.println("普通操作,输入支付密码即可");
            System.out.println(name + ": " + request.getRequestType() + ", 金额:" + request.getMoney() + " 处理完成");
        } else {
            if (superior != null) {
                superior.handlerRequest(request);
            }
        }
    }
}

// 中级风控
public class SecondRiskControlManager extends RiskControlManager {
    public SecondRiskControlManager(String name) {
        super(name);
    }

    @Override
    public void handlerRequest(Request request) {
        if (request.getMoney() > 1000 && request.getMoney() < 10000) {
            System.out.println("稍大额操作,输入支付密码+短信验证码即可");
            System.out.println(name + ": " + request.getRequestType() + ", 金额:" + request.getMoney() + " 处理完成");
        } else {
            if (superior != null) {
                superior.handlerRequest(request);
            }
        }
    }
}

// 高级风控
public class ThirdRiskControlManager extends RiskControlManager {
    public ThirdRiskControlManager(String name) {
        super(name);
    }

    @Override
    public void handlerRequest(Request request) {
        if (request.getMoney() >= 10000) {
            System.out.println("大额操作,输入支付密码+验证码+人脸识别");
            System.out.println(name + ": " + request.getRequestType() + ", 金额:" + request.getMoney() + " 处理完成");
        } else {
            if (superior != null) {
                superior.handlerRequest(request);
            }
        }
    }
}

// 使用
public static void main(String[] args) {
    RiskControlManager firstControlManager = new FirstRiskControlManager("初级风控");
    RiskControlManager secondControlManager = new SecondRiskControlManager("中级风控");
    RiskControlManager thirdControlManager = new ThirdRiskControlManager("高级风控");

    firstControlManager.setSuperior(secondControlManager);
    secondControlManager.setSuperior(thirdControlManager);

    Request request1 = new Request();
    request1.setRequestType("TRANSFER");
    request1.setMoney(20000);

    firstControlManager.handlerRequest(request1);
}

(五)优点

  1. 降低耦合度:客户端无需知道具体的处理者,只需将请求发送到责任链上。

  2. 动态调整:可以通过改变链的顺序动态地新增或删除处理类。

  3. 符合开闭原则:可以方便地增加新的处理类,而无需修改现有代码。

(六)缺点

  1. 性能问题:如果链路较长,可能会对系统性能产生一定影响。

  2. 调试困难:在调试时,由于责任链的动态性,可能会增加调试的复杂性。

二、命令模式(Command Pattern)

(一)定义

命令模式将请求封装为一个对象,从而使用户可用不同的请求对客户进行参数化。命令模式属于行为型模式,它将请求的发送者和接收者解耦。

(二)应用场景

  1. GUI应用程序:如按钮点击事件、菜单操作等。

  2. 智能家居控制:通过命令模式可以将不同的操作封装为命令对象。

(三)角色

  • Command(抽象命令):定义了执行操作的接口。

  • ConcreteCommand(具体命令):实现抽象命令接口,绑定一个接收者,并调用接收者的操作。

  • Receiver(接收者):知道如何实施与执行一个请求相关的操作。

  • Invoker(请求者):要求命令对象执行请求。

  • Client(客户端):创建一个具体命令对象并设定其接收者。

(四)实现案例

以下是一个智能家居控制的实现案例:

// 接收者
public class ConditionReceiver {
    public void on() {
        System.out.println("空调开启了");
    }

    public void off() {
        System.out.println("空调关闭了");
    }

    public void cool() {
        System.out.println("空调开始制冷");
    }

    public void warm() {
        System.out.println("空调开始制暖");
    }
}

// 抽象命令
public interface Command {
    void execute();
}

// 具体命令:开启空调
public class OnCommand implements Command {
    private ConditionReceiver receiver;

    public OnCommand(ConditionReceiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        receiver.on();
    }
}

// 具体命令:关闭空调
public class OffCommand implements Command {
    private ConditionReceiver receiver;

    public OffCommand(ConditionReceiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        receiver.off();
    }
}

// 请求者:APP
public class AppInvoker {
    private Command onCommand;
    private Command offCommand;

    public void setOnCommand(Command onCommand) {
        this.onCommand = onCommand;
    }

    public void setOffCommand(Command offCommand) {
        this.offCommand = offCommand;
    }

    public void on() {
        onCommand.execute();
    }

    public void off() {
        offCommand.execute();
    }
}

// 使用
public static void main(String[] args) {
    ConditionReceiver receiver = new ConditionReceiver();
    Command onCommand = new OnCommand(receiver);
    Command offCommand = new OffCommand(receiver);

    AppInvoker appInvoker = new AppInvoker();
    appInvoker.setOnCommand(onCommand);
    appInvoker.setOffCommand(offCommand);

    appInvoker.on();
    appInvoker.off();
}

(五)优点

  1. 降低耦合度:调用者与接收者之间没有直接依赖关系。

  2. 扩展性强:可以很容易地添加新的命令类。

(六)缺点

  1. 命令类过多:可能会导致系统中存在大量的命令类。

三、迭代器模式(Iterator Pattern)

(一)定义

迭代器模式提供了一种方法顺序访问一个聚合对象中的各个元素,而无需暴露该对象的内部实现。迭代器模式属于行为型模式,广泛应用于集合操作中。

(二)应用场景

  1. 集合遍历:如Java中的ListSetMap等集合都提供了迭代器。

  2. 自定义集合:当需要对自定义集合进行遍历时,可以实现迭代器模式。

(三)角色

  • Aggregate(抽象聚合):定义了创建具体迭代器的接口。

  • ConcreteAggregate(具体聚合):实现抽象聚合接口,返回一个具体迭代器。

  • Iterator(抽象迭代器):定义了访问和遍历元素的接口。

  • ConcreteIterator(具体迭代器):实现抽象迭代器接口,记录遍历中的当前位置。

(四)实现案例

以下是一个自定义集合容器的实现案例:

// 抽象迭代器
public interface Iterator {
    Object next();
    boolean hasNext();
}

// 具体迭代器
public class ConcreteIterator implements Iterator {
    private List list;
    private int index = 0;

    public ConcreteIterator(List list) {
        this.list = list;
    }

    @Override
    public Object next() {
        Object obj = null;
        if (this.hasNext()) {
            obj = this.list.get(index);
            index++;
        }
        return obj;
    }

    @Override
    public boolean hasNext() {
        return index < list.size();
    }
}

// 抽象聚合
public interface ICollection {
    void add(Object obj);
    void remove(Object obj);
    Iterator iterator();
}

// 具体聚合
public class MyCollection implements ICollection {
    private List list = new ArrayList();

    @Override
    public void add(Object obj) {
        list.add(obj);
    }

    @Override
    public void remove(Object obj) {
        list.remove(obj);
    }

    @Override
    public Iterator iterator() {
        return new ConcreteIterator(list);
    }
}

// 使用
public static void main(String[] args) {
    ICollection collection = new MyCollection();
    collection.add("小滴课堂老王");
    collection.add("小滴课堂Anna小姐姐");
    collection.add("小滴课堂二当家小D");

    Iterator iterator = collection.iterator();
    while (iterator.hasNext()) {
        Object obj = iterator.next();
        System.out.println(obj);
    }
}

(五)优点

  1. 封装性:不暴露集合的内部结构,同时允许外部代码透明地访问集合内部的数据。

  2. 灵活性:支持以不同的方式遍历一个聚合对象。

(六)缺点

  1. 性能问题:对于简单的遍历(如数组或有序列表),使用迭代器可能会增加额外的开销。

  2. 并发问题:在遍历的同时更改迭代器所在的集合结构可能会导致异常。

行为型设计模式在软件开发中具有重要的作用,责任链模式、命令模式和迭代器模式是其中的典型代表。责任链模式通过定义责任链,降低了请求发送者与接收者之间的耦合关系;命令模式通过封装请求,实现了调用者与接收者之间的解耦;迭代器模式通过定义迭代器,实现了对集合的透明访问。在实际开发中,合理运用这些设计模式,可以提高代码的可维护性和可扩展性,降低系统的复杂度。

你可能感兴趣的:(设计模式,设计模式,责任链模式,命令模式)