什么是命令模式 将单个请求封装成单个对象,客户端可调用不同请求完成任务。对请求有所记录,或可支持撤销等操作。
命令模式的适用场景 需要支持事务操作。 需要有类似于日志记录的功能,可在执行之前做修改操作,或意外丢失可执行恢复工作。 抽象出需要执行的动作,以参数的形式提供给命令者。
命令模式的角色 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(); } }运行结果:
您的菜单是: 香喷喷的烤肉!命令模式总结 命令模式其实就是通过中间人的记录,来把要求者的请求记录在案,记录可更改操作,确认后统一交付执行者。 优点:更低的耦合度,灵活控制和易扩展性。可记录命令执行的结构,方便补救措施施行。 缺点:类比较庞大,大量衍生类的创建,如果我有成千上万种食物,那么这样下来整个系统会很雍容。