一、命令模式
1、UML图
Command模式将请求封装到一个对象Command中,将请求的接收者存放到具体的ConcreteCommand类中,实现调用操作的对象Client和操作的具体实现者Receiver之间的解耦。
Command模式结构中,将请求的接收者(处理者) Receiver放到Command的具体子类ConcreteCommand中,当请求到来时(Invoker发出Invoke消息激活Command对象),ConcreteCommand将处理请求交给Receiver对象进行处理。
2、代码:
class Receiver{
public void Action() {
System.out.println("执行请求!");
}
}
abstract class Command{
protected Receiver receiver;
public Command(Receiver receiver) {
this.receiver=receiver;
}
abstract public void Excute();
}
class ConcreteCommand extends Command{
public ConcreteCommand(Receiver receiver) {
super(receiver);
}
@Override
public void Excute() {
// TODO Auto-generated method stub
receiver.Action();
}
}
class Invoker{
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void ExecuteCommand() {
command.Excute();
}
}
public class Main{
public static void main(String[] args){
Receiver r=new Receiver();
Command c=new ConcreteCommand(r);
Invoker i=new Invoker();
i.setCommand(c);
i.ExecuteCommand();
}
}
3、在什么情况下应当使用命令模式?
如果需要在不同的时刻指定、排列和执行请求,可以选用命令模式,把这些请求封装成为命令对象,然后实现把请求队列化。
.如果需要支持取消操作,可以选用命令模式,通过管理命令对象,能很容易的实现命令的恢复和重做的功能。
4、优点:
命令模式使新的命令很客易地被加入到系统里。
允许接收请求的一方决定是否要否决(Veto)请求。
能较客易地设计一个命令队列。
可以容易地实现对请求的Undo和Redo.
在需要的情况下,可以较容易地将命令记入日志。
命令模式把请求一个操作的对象与执行操作的对象分割开。
命令类与其他任何别的类一样,可以修改和推广 。
二、实例:
在街边的烧烤摊点餐场景:直接和老板说需要点什么
class Barbecuer{
//烤羊肉
public void BakeMutton() {
System.out.println("烤羊肉串!");
}
//烤鸡翅
public void BakeChickenWing() {
System.out.println("烤鸡翅!");
}
}
public class Main{
public static void main(String[] args){
Barbecuer boy=new Barbecuer();
boy.BakeMutton();
boy.BakeMutton();
boy.BakeMutton();
boy.BakeChickenWing();
boy.BakeMutton();
boy.BakeMutton();
boy.BakeChickenWing();
}
}
//结果为:
烤羊肉串!
烤羊肉串!
烤羊肉串!
烤鸡翅!
烤羊肉串!
烤羊肉串!
烤鸡翅!
出现问题:客户端发出命令或者请求,不关心请求的真正接收者是谁,也不关心具体如何实现,而且同一个请求的动作可以有不同的请求内容,当然具体的处理功能也不一样,该怎么实现?
**例题2:**在烧烤店点餐的情景:直接告诉服务员要什么要多少,服务员在订单上记下之后,直接将订单送往后厨,然后招待其他刚进来的顾客。
class Barbecuer{
//烤羊肉
public void BakeMutton() {
System.out.println("烤羊肉串!");
}
//烤鸡翅
public void BakeChickenWing() {
System.out.println("烤鸡翅!");
}
}
abstract class Command{
protected Barbecuer receiver;
public Command(Barbecuer receiver) {
this.receiver=receiver;
}
public abstract void ExcuteCommand();
}
//烤羊肉串命令
class BakeMuttonCommand extends Command{
public BakeMuttonCommand(Barbecuer receiver) {
super(receiver);
// TODO Auto-generated constructor stub
}
@Override
public void ExcuteCommand() {
// TODO Auto-generated method stub
receiver.BakeMutton();
}
}
class BakeChickenWingCommand extends Command{
public BakeChickenWingCommand(Barbecuer receiver) {
super(receiver);
// TODO Auto-generated constructor stub
}
@Override
public void ExcuteCommand() {
// TODO Auto-generated method stub
receiver.BakeChickenWing();
}
}
//服务员
class Waiter{
private Command command;
//设置订单
public void SetOrder(Command command) {
this.command=command;
}
//通知执行
public void Notify() {
command.ExcuteCommand();
}
}
public class Main{
public static void main(String[] args){
//开店前的准备
Barbecuer boy=new Barbecuer();
Command bakeMuttonCommand1=new BakeMuttonCommand(boy);
Command bakeMuttonCommand2=new BakeMuttonCommand(boy);
Command bakeChikenWingCommand1=new BakeChickenWingCommand(boy);
Waiter girl=new Waiter();
//开门营业顾客点菜
girl.SetOrder(bakeMuttonCommand1);
girl.Notify();
girl.SetOrder(bakeMuttonCommand2);
girl.Notify();
girl.SetOrder(bakeChikenWingCommand1);
girl.Notify();
}
}
//结果为:
烤羊肉串!
烤羊肉串!
烤鸡翅!