什么是命令模式
将单个请求封装成单个对象,客户端可调用不同请求完成任务。对请求有所记录,或可支持撤销等操作。
命令模式的适用场景
需要支持事务操作。
需要有类似于日志记录的功能,可在执行之前做修改操作,或意外丢失可执行恢复工作。
抽象出需要执行的动作,以参数的形式提供给命令者。
命令模式的角色
Receiver:接收者角色。执行具体逻辑的角色。
Command:命令角色,定义总的命令抽象接口。
ConcreteCommand:具体命令角色,Command的具体实现。
Invoker:请求者角色,调用命令对象执行确定的请求。
Client:客户端角色。
命令模式用例
我们到餐厅聚餐,餐厅有服务员,厨师等角色,我们点餐,服务员记录在案,我们还可以反悔,取消点过的菜品,只要在厨师未做之前就可以的,而我们点菜并未与厨师联系,服务员相当于Invoker角色,产品确定后向厨师Receiver发送命令。
UML类图
服务员Waiter类:
public class Waiter {
//模仿记录菜单的列表
private ArrayList<AbstractCommand> acs = new ArrayList<AbstractCommand>();
public void addCommand(AbstractCommand ac){
acs.add(ac);
}
public void deleteCommand(AbstractCommand ac){
acs.remove(ac);
}
public void notifyCook(){
System.out.println("您的菜单是:");
for(AbstractCommand ac:acs){
System.out.println(ac.makeFood());
}
}
}
抽象类AbstractCommand:
public abstract class AbstractCommand {
public abstract String makeFood();
}
具体类MeatCommand:
public class MeatCommand extends AbstractCommand {
@Override
public String makeFood() {
return "香喷喷的烤肉!";
}
}
具体类CakeCommand:
public class CakeCommand extends AbstractCommand {
@Override
public String makeFood() {
return "可口的蛋糕!";
}
}
测试类:
public class Test {
public static void main(String[] args) {
CakeCommand cake = new CakeCommand();
MeatCommand meat = new MeatCommand();
Waiter waiter = new Waiter();
//添加两个菜品
waiter.addCommand(cake);
waiter.addCommand(meat);
//考虑后觉得吃不了取消一个
waiter.deleteCommand(cake);
//通知后厨做菜
waiter.notifyCook();
}
}
运行结果:
您的菜单是:
香喷喷的烤肉!
命令模式总结
命令模式其实就是通过中间人的记录,来把要求者的请求记录在案,记录可更改操作,确认后统一交付执行者。
优点:更低的耦合度,灵活控制和易扩展性。可记录命令执行的结构,方便补救措施施行。
缺点:类比较庞大,大量衍生类的创建,如果我有成千上万种食物,那么这样下来整个系统会很雍容。