责任链模式 Chain of Responsibility
1、什么是责任链模式
责任链模式为请求创建一个接收者对象的链,每个接收者都包含对另一个接收者的引用。如果一个对象不能处理请求,它会将请求传递给链中的下一个接收者,如此模式下,请求沿着链传递,直到有一个对象能够处理它。
2、为什么使用责任链模式
- 解耦发送者和接收者:责任链模式允许请求的发送者和接收者解耦,发送者不需要知道请求的处理者是谁,处理者也不需要知道请求的发送者是谁。
- 动态添加处理者:可以动态地添加或修改处理者,灵活性较高。新的处理者可以很容易地被插入到链中。
- 避免请求的发送者与接收者直接耦合:责任链模式避免了直接连接发送者与接收者,降低了系统的耦合度。
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;
}
@Override
public 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;
}
@Override
public 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;
}
@Override
public 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、是否存在缺陷和不足
- 如果责任链没有被正确配置,存在请求漏处理的风险。
- 链中的每个处理者都需要判断是否能够处理请求,性能上会有一些额外的开销,对性能有一定影响的风险。
5、如何缓解缺陷和不足
- 在责任链的末尾添加一个默认处理者,确保所有请求都能被处理。
- 在链中添加一些优化措施,减少不必要的判断,提高性能。
策略模式 Strategy
1、什么是策略模式
策略模式是定义一系列的算法,将每个算法封装起来,并使它们可以相互替换。策略模式使得算法的变化独立于使用算法的客户端。
2、为什么使用策略模式
- 算法独立性:策略模式将每个算法封装成一个策略类,使得算法可以独立于其他部分变化,提高了代码的灵活性。
- 易于扩展:新的算法可以很容易地添加到系统中,不需要修改已有的代码。
- 避免使用条件语句:策略模式消除了大量的条件语句,使得代码更加清晰和易于维护。
3、如何使用策略模式
设计实现一个简单的图像处理应用,根据用户的选择应用不同的滤镜
// 策略接口
interface FilterStrategy {
void applyFilter(String fileName);
}
// 具体策略1:黑白滤镜
class BlackAndWhiteFilter implements FilterStrategy {
@Override
public void applyFilter(String fileName) {
System.out.println("Applying Black and White filter to " + fileName);
}
}
// 具体策略2:高对比度滤镜
class HighContrastFilter implements FilterStrategy {
@Override
public void applyFilter(String fileName) {
System.out.println("Applying High Contrast filter to " + fileName);
}
}
// 具体策略3:模糊滤镜
class BlurFilter implements FilterStrategy {
@Override
public 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、是否存在缺陷和不足
- 在策略模式下,客户端需要直到所有的策略类,然后根据自己的场景选择合适的策略去调用执行,可能会导致策略类过多的时候而复杂度增大。
5、如何缓解缺陷和不足
- 可以结合工厂模式,由工厂负责创建具体的策略对象,减轻客户端的责任。
- 可以通过依赖注入的方式,将具体的策略对象注入到上下文类中,降低客户端的耦合度。