23种设计模式总览
创建型模式
结构型模式
- 外观模式(Facade)
- 适配器模式(Adapter)
- 代理模式(Proxy)
- 组合模式(Composite)
- 享元模式(Flyweight)
- 装饰模式(Decorator)
- 桥接模式(Bridge)
行为型模式
- 中介者模式(Mediator)
- 观察者模式(Observer)
- 命令模式(Command)
- 迭代器模式(Iterator)
- 模板方法模式(Template Method)
- 策略模式(Strategy)
- 状态模式(State)
- 备忘录模式(Memento)
- 解释器模式(Interpreter)
- 职责链模式(Chain of Responsibility)
- 访问者模式(Visitor)
定义
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
优缺点
优点:
1、降低耦合度。它将请求的发送者和接收者解耦。
2、简化了对象。使得对象不需要知道链的结构。
3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
4、增加新的请求处理类很方便。
缺点:
1、不能保证请求一定被接收。
2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
3、可能不容易观察运行时的特征,有碍于除错。
场景
现实中,请假的OA申请,请假天数如果是半天到1天,可能直接主管批准即可;
如果是1到3天的假期,需要部门经理批准;
如果是3天到30天,则需要总经理审批;
大于30天,正常不会批准。
实现
- 员工提交请求类:LeaveRequest。
- 抽象的请假责任处理类:AbstractLeaveHandler。
- 直接主管审批处理类:DirectLeaderLeaveHandler。
- 部门经理处理类:DeptManagerLeaveHandler。
- 总经理处理类: GManagerLeaveHandler。
//员工提交请求类
public class LeaveRequest {
/**
* 天数
*/
private int leaveDays;
/**
* 姓名
*/
private String name;
public LeaveRequest(int leaveDays, String name) {
this.leaveDays = leaveDays;
this.name = name;
}
public int getLeaveDays() {
return leaveDays;
}
public void setLeaveDays(int leaveDays) {
this.leaveDays = leaveDays;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//请假责任链抽象处理类
abstract public class AbstractLeaveHandler {
/**
* 直接主管审批处理的请假天数
*/
public int MIN = 1;
/**
* 部门经理处理的请假天数
*/
public int MIDDLE = 3;
/**
* 总经理处理的请假天数
*/
public int MAX = 30;
/**
* 下一个处理节点(即更高级别的领导)
*/
public AbstractLeaveHandler nextHandler;
/**
* 设置下一节点
*/
public void setNextHandler(AbstractLeaveHandler handler) {
this.nextHandler = handler;
}
/**
* 处理请假的请求,子类实现
*/
abstract public void handlerRequest(LeaveRequest request);
}
//直接主管处理类
public class DirectLeaderLeaveHandler extends AbstractLeaveHandler {
@Override
public void handlerRequest(LeaveRequest request) {
if (request.getLeaveDays() <= this.MIN) {
System.out.println("直接主管:已经处理;流程结束。");
return;
}
if (null != this.nextHandler) {
this.nextHandler.handlerRequest(request);
} else {
System.out.println("审批拒绝!");
}
}
}
// 部门经理处理类
public class DeptManagerLeaveHandler extends AbstractLeaveHandler {
@Override
public void handlerRequest(LeaveRequest request) {
if (request.getLeaveDays() > this.MIN && request.getLeaveDays() <= this.MIDDLE) {
System.out.println("部门经理:已经处理;流程结束。");
return;
}
if (null != this.nextHandler) {
this.nextHandler.handlerRequest(request);
} else {
System.out.println("审批拒绝!");
}
}
}
//总经理处理类
public class GManagerLeaveHandler extends AbstractLeaveHandler {
@Override
public void handlerRequest(LeaveRequest request) {
if (request.getLeaveDays() > this.MIDDLE && request.getLeaveDays() <= this.MAX) {
System.out.println("总经理:已经处理;流程结束。");
return;
}
if (null != this.nextHandler) {
this.nextHandler.handlerRequest(request);
} else {
System.out.println("审批拒绝!");
}
}
}
演示
public class Test {
public static void main(String[] args) {
LeaveRequest request1 = new LeaveRequest(1, "小明");
LeaveRequest request2 = new LeaveRequest(3, "小明");
LeaveRequest request3 = new LeaveRequest(7, "小明");
AbstractLeaveHandler directLeaderLeaveHandler = new DirectLeaderLeaveHandler();
DeptManagerLeaveHandler deptManagerLeaveHandler = new DeptManagerLeaveHandler();
GManagerLeaveHandler gManagerLeaveHandler = new GManagerLeaveHandler();
//直接主管下一级为部门经理
directLeaderLeaveHandler.setNextHandler(deptManagerLeaveHandler);
//部门经理下一级为总经理
deptManagerLeaveHandler.setNextHandler(gManagerLeaveHandler);
//小明请假直接领导处理
directLeaderLeaveHandler.handlerRequest(request1);
directLeaderLeaveHandler.handlerRequest(request2);
directLeaderLeaveHandler.handlerRequest(request3);
}
}
- 1天,运行输出: 直接主管:已经处理;流程结束。
- 3天,运行输出: 部门经理:已经处理;流程结束。
- 7天,运行输出: 总经理:已经处理;流程结束。
总结
责任链主要重在责任分离处理,让各个节点各司其职。
责任链上的各个节点都有机会处理事务,但是也可能不会受理请求。
责任链比较长,调试时可能会比较麻烦。
责任链一般用于处理流程节点之类的实际业务场景中。