持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第33天,点击查看活动详情。
责任链模式&吗&命令模式
责任链模式&命令模式,责任链模式适合处理存在链式算法的业务场景,将每一个场景抽象出来作为节点,可以灵活组合适应不同场景需要。命令模式模式是将命令发出者和命令执行者解耦,使得各自互不影响,提高代码健壮性
责任链模式
责任链模式(Chain of Responsibility),属于行为型模式。该模式存在多个对象每一个对象持有下一个对象的引用,这样就会形成一条链,直到某一对象决定处理该请求。对于客户端也就是调用者可以隐瞒内部实现。并且可以灵活的修改且不影响客户端调用逻辑。要求同一时刻命令只允许由一个对象传给另一个对象,而不允许同一时刻传给多个对象。
一般由于一些流程化的业务逻辑。
实现
定义抽象接口:
public interface Handler {
/**
* 做什么操作
*/
void operate();
}
抽象父类:
@Data
public abstract class AbstractHandler {
/**
* 将对象组合进来
*/
private Handler handler;
}
实现类:
@AllArgsConstructor
public class HandlerImpl extends AbstractHandler implements Handler {
private String name;
@Override
public void operate() {
System.out.println(this.name);
final Handler handler = super.getHandler();
if (!ObjectUtils.isEmpty(handler)) {
handler.operate();
}
}
}
测试:
public class ChainOfResponsibilityTest {
@Test
public void test() {
HandlerImpl handler1 = new HandlerImpl("1");
HandlerImpl handler2 = new HandlerImpl("2");
HandlerImpl handler3 = new HandlerImpl("3");
HandlerImpl handler4 = new HandlerImpl("4");
handler1.setHandler(handler2);
handler2.setHandler(handler3);
handler3.setHandler(handler4);
handler1.operate();
}
}
应用
生活中关于责任链模式的模型还是很多的。比如说买保险,保险公司对于保险的赔付率是由一定算法得出的。那么就是一条链下来某个节点触犯了条件那么就不可以买保险。
假设这里有一个保险公司的产品叫做“金致人生”,对于投保人有以下限制条件:
- 年龄不大于80岁
- 吸烟年龄小于10年
- 不参加极限运动
- 职业危险等级为 5 以下
那么我们就可以抽象出来,每一个条件都是责任链上的一个节点,就是一个handler
命令模式
命令模式(Command Pattern)属于行为模式,将一个请求封装为一个对象,使发出请求的责任与执行请求的责任分开。将命令发出者与命令接收者进行解耦,两者通过命令对象进行沟通。
包含角色
- 抽象命令类(Command),定义命令抽象接口
- 具体命令类(Concrete Command),抽象命令类的实现,将命令接受者组合进来,调用命令接受者的具体功能来完成命令的执行。
- 命令接受者(Receiver),命令的具体执行者
- 命令发出者或调用者(Invoker),命令发出者,将命令组合进来,通过调用命令来完成相关业务
实现
以公司领导安排任务为例。领导负责一个项目的进度,一般会有很多的员工,领导为多个员工下达不同的指令,员工负责具体执行对应任务。
在此模型中领导是命令发出者,员工是命令接受者,任务就是命令。领导无需关系任务具体完成细节,他只需要知道任务完成结果,每个任务分配给对应员工,员工具体执行业务。
抽像命令接口:
public interface Command {
/**
* 命令方法
*/
void execute();
}
具体命令:将具体负责人组合进来
@Data
@AllArgsConstructor
public class ConcreteCommand implements Command {
/**
* 每个任务都有负责人
*/
private Receiver receiver;
@Override
public void execute() {
//具体负责人去完成任务
receiver.doWork();
}
}
命令接收者:
@Data
@Accessors(chain = true)
public class Receiver {
String name;
public void doWork() {
System.out.println(this.name + "完成任务");
}
}
命令发出者:
组合多个命令:
public class Invoker {
/**
* 老板将一个项目拆分为许多模块,每个模块就是一个命令
*/
private List<Command> commandList = new ArrayList<>();
public void addCommand(Command command){
System.out.println("添加任务");
commandList.add(command);
}
public void delCommand(Command command){
System.out.println("移除任务");
commandList.remove(command);
}
public void doCommand(){
//完成任务
commandList.forEach(Command::execute);
}
}
测试:
public class Client {
public static void main(String[] args) {
Invoker invoker = new Invoker();
Receiver receiver1 = new Receiver().setName("employee01");
Receiver receiver2 = new Receiver().setName("employee02");
Receiver receiver3 = new Receiver().setName("employee03");
Receiver receiver4 = new Receiver().setName("employee04");
Command command1 = new ConcreteCommand(receiver1);
Command command2 = new ConcreteCommand(receiver2);
Command command3 = new ConcreteCommand(receiver3);
Command command4 = new ConcreteCommand(receiver4);
invoker.addCommand(command1);
invoker.addCommand(command2);
invoker.addCommand(command3);
invoker.addCommand(command4);
invoker.doCommand();
}
}