命令(Command)模式【行为模式第九篇】
命令(Command)模式:
命令模式属于对象的行为模式。命令模式又称为行动模式或交易模式。
命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令
的撤销和恢复功能。
命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。每一个命令都是一个操作:
请求的一方发出请求要求执行一个操作;接受的一方收到请求,并执行操作。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必
知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
命令允许请求的一方和接收请求的一方能够独立演化,从而具有一下的优点:
(1)命令模式使新的命令很容易地被加入到系统里。
(2)允许接收请求的一方决定是否要否决要求。
(3)能较容易地设计一个命令队列。
(4)可以容易地实现对请求的Undo和Redo。
(5)在需要的情况下,可以较容易地将命令记录日志。
一、命令模式涉及到的五个角色:
1、客户角色:创建了一个具体命令对象并确定其接收者。
2、命令角色:声明了一个给所有具体命令类的抽象接口。这是一个抽象角色,通常由一个java接口或java抽象类实现。
3、具体命令角色:定义一个接受者和行为之间的弱耦合;实现execute方法,负责调用接收者的相应操作。execute方法通常叫做
执行方法。
4、请求者(Invoke)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。
5、接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
//客户端public class Client{public static void main(String[] args){Receiver receiver = new Receiver();Command command = new ConcreteCommand(receiver);Invoker invoker = new Invoker(command);invoker.action();}}//请求者角色public class Invoker{private Command command;public Invoker(Command command){this.command = command;}public void action(){command.execute();}}//接收者public class Receiver{public Receiver(){//..............}//行动方法public void action(){System.out.println("Action has been taken.");}}//抽象命令角色public interface Command{void execute();}//具体命令类public class ConcreteCommand implements Command{private Receiver receiver;public ConcreteCommand(Receiver receiver){this.receiver = receiver;}public void execute(){receiver.action();}}命令模式的活动序列(1)客户端创建了一个ConcreteCommand对象,并指明了接收者;(2)请求者对象保存了ConcreteCommand对象;(3)请求者对象通过调用action()方法发出请求。如果命令是能撤销(Undo)的,那么ConcreteCommand保存了 调用execute()方法之前的状态。(4)ConcreteCommand对象调用接收的一方的方法执行请求。//一个例子(创世纪)//抽象命令类public interface CommandFromGod{public void execute();}//请求角色import java.awt.*;import java.awt.event.*;public class TheWorld extends Frame implements ActionListener{private LetThereBeLightCommand btnLight;private LetThereBeLandCommand btnLand;private ResetCommand btnReset;private GodRestsCommand btnExit;private Panel p;public TheWorld(){super("This is the world,and God says...");p = new Panel();p.setBackground(Color.black);add(p);btnLight = new LetThereBeLightCommand("Let there be light",p);btnLand = new LetThereBeLandCommand("Let there be land",p);btnReset = new ResetCommand("Reset",p);btnExit = new GodRestsCommand("God rests");p.add(btnLight);p.add(btnLand);p.add(btnReset);p.add(btnExit);btnLight.addActionListener(this);btnLand.addActionListener(this);btnReset.addActionListener(this);btnExit.addActionListener(this);setBounds(100,100,400,200);setVisible(true);}public void actionPerformed(ActionEvent e){Command obj = (Command)e.getSource();obj.execute();}public static void main(String[] args){new TheWorld();}}import java.awt.*;import java.awt.event.*;public class LetThereBeLightCommand extends Button implements CommandFromGod{private Panel p;public LetThereBeLightCommand(String caption,Panel p){super(caption);this.p = p;}public void execute(){p.setBackground(Color.white);}}import java.awt.*;import java.awt.event.*;public class LetThereBeLandCommand extends Button implements CommandFromGod{private Panel p;public LetThereBeLandCommand(String caption,Panel p){super(caption);this.p = p;}public void execute(){p.setBackground(Color.orange);}}import java.awt.*;import java.awt.event.*;public class ResetCommand extends Button implements CommandFromGod{private Panel p;public ResetCommand(String caption,Panel p){super(caption);this.p = p;}public void execute(){p.setBackground(Color.black);}}import java.awt.*;import java.awt.event.*;public class GodRestsCommand extends Button implements CommandFromGod{public GodRestsCommand(String caption){super(caption);}public void execute(){System.exit(0);}}