行为型设计模式(二)责任链模式  策略模式

责任链模式 Chain of Responsibility

1、什么是责任链模式

责任链模式为请求创建一个接收者对象的链,每个接收者都包含对另一个接收者的引用。如果一个对象不能处理请求,它会将请求传递给链中的下一个接收者,如此模式下,请求沿着链传递,直到有一个对象能够处理它。

2、为什么使用责任链模式

  1. 解耦发送者和接收者:责任链模式允许请求的发送者和接收者解耦,发送者不需要知道请求的处理者是谁,处理者也不需要知道请求的发送者是谁。
  2. 动态添加处理者:可以动态地添加或修改处理者,灵活性较高。新的处理者可以很容易地被插入到链中。
  3. 避免请求的发送者与接收者直接耦合:责任链模式避免了直接连接发送者与接收者,降低了系统的耦合度。

3、如何使用责任链模式

设计实现一个关于请假审批的链

// 请求类
class LeaveRequest {private String employee;private int days;LeaveRequest(String employee, int days) {this.employee = employee;this.days = days;}String getEmployee() {return employee;}int getDays() {return days;}
}// 处理者接口
interface Approver {void processRequest(LeaveRequest request);
}// 具体处理者1
class Supervisor implements Approver {private final int MAX_LEAVES = 3;private Approver nextApprover;Supervisor(Approver nextApprover) {this.nextApprover = nextApprover;}@Overridepublic void processRequest(LeaveRequest request) {if (request.getDays() <= MAX_LEAVES) {System.out.println("Supervisor approves leave for " + request.getEmployee() + " (" + request.getDays() + " days)");} else if (nextApprover != null) {nextApprover.processRequest(request);}}
}// 具体处理者2
class Manager implements Approver {private final int MAX_LEAVES = 7;private Approver nextApprover;Manager(Approver nextApprover) {this.nextApprover = nextApprover;}@Overridepublic void processRequest(LeaveRequest request) {if (request.getDays() <= MAX_LEAVES) {System.out.println("Manager approves leave for " + request.getEmployee() + " (" + request.getDays() + " days)");} else if (nextApprover != null) {nextApprover.processRequest(request);}}
}// 具体处理者3
class Director implements Approver {private Approver nextApprover;Director(Approver nextApprover) {this.nextApprover = nextApprover;}@Overridepublic void processRequest(LeaveRequest request) {System.out.println("Director approves leave for " + request.getEmployee() + " (" + request.getDays() + " days)");}
}// 客户端代码
public class Client {public static void main(String[] args) {Approver director = new Director(null);Approver manager = new Manager(director);Approver supervisor = new Supervisor(manager);// 创建请假请求LeaveRequest request1 = new LeaveRequest("Alice", 2);LeaveRequest request2 = new LeaveRequest("Bob", 5);LeaveRequest request3 = new LeaveRequest("Charlie", 8);// 处理请假请求supervisor.processRequest(request1);supervisor.processRequest(request2);supervisor.processRequest(request3);}
}

4、是否存在缺陷和不足

  1. 如果责任链没有被正确配置,存在请求漏处理的风险。
  2. 链中的每个处理者都需要判断是否能够处理请求,性能上会有一些额外的开销,对性能有一定影响的风险。

5、如何缓解缺陷和不足

  1. 在责任链的末尾添加一个默认处理者,确保所有请求都能被处理。
  2. 在链中添加一些优化措施,减少不必要的判断,提高性能。

策略模式 Strategy

1、什么是策略模式

策略模式是定义一系列的算法,将每个算法封装起来,并使它们可以相互替换。策略模式使得算法的变化独立于使用算法的客户端。

2、为什么使用策略模式

  1. 算法独立性:策略模式将每个算法封装成一个策略类,使得算法可以独立于其他部分变化,提高了代码的灵活性。
  2. 易于扩展:新的算法可以很容易地添加到系统中,不需要修改已有的代码。
  3. 避免使用条件语句:策略模式消除了大量的条件语句,使得代码更加清晰和易于维护。

3、如何使用策略模式

设计实现一个简单的图像处理应用,根据用户的选择应用不同的滤镜

// 策略接口
interface FilterStrategy {void applyFilter(String fileName);
}// 具体策略1:黑白滤镜
class BlackAndWhiteFilter implements FilterStrategy {@Overridepublic void applyFilter(String fileName) {System.out.println("Applying Black and White filter to " + fileName);}
}// 具体策略2:高对比度滤镜
class HighContrastFilter implements FilterStrategy {@Overridepublic void applyFilter(String fileName) {System.out.println("Applying High Contrast filter to " + fileName);}
}// 具体策略3:模糊滤镜
class BlurFilter implements FilterStrategy {@Overridepublic void applyFilter(String fileName) {System.out.println("Applying Blur filter to " + fileName);}
}// 上下文类,维护一个策略对象
class ImageProcessor {private FilterStrategy filterStrategy;// 设置策略对象void setFilterStrategy(FilterStrategy filterStrategy) {this.filterStrategy = filterStrategy;}// 应用滤镜void applyFilter(String fileName) {if (filterStrategy != null) {filterStrategy.applyFilter(fileName);}}
}// 客户端代码
public class Client {public static void main(String[] args) {ImageProcessor imageProcessor = new ImageProcessor();// 应用黑白滤镜imageProcessor.setFilterStrategy(new BlackAndWhiteFilter());imageProcessor.applyFilter("image1.jpg");// 应用高对比度滤镜imageProcessor.setFilterStrategy(new HighContrastFilter());imageProcessor.applyFilter("image2.jpg");// 应用模糊滤镜imageProcessor.setFilterStrategy(new BlurFilter());imageProcessor.applyFilter("image3.jpg");}
}

4、是否存在缺陷和不足

  1. 在策略模式下,客户端需要直到所有的策略类,然后根据自己的场景选择合适的策略去调用执行,可能会导致策略类过多的时候而复杂度增大。

5、如何缓解缺陷和不足

  1. 可以结合工厂模式,由工厂负责创建具体的策略对象,减轻客户端的责任。
  2. 可以通过依赖注入的方式,将具体的策略对象注入到上下文类中,降低客户端的耦合度。