命令模式(命令也是类)
用处
请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
角色
- Command(命令)
该角色负责定义命令的接口(API) - ConcreteCommand(具体的命令)
该角色负责实现Command角色中定义的接口(API)。 - Recevier(接收者)
该角色是Command角色执行命令时的对象,也可以称其为命令接收者。 - Client(请求者)
该角色负责生成ConcreteCommand并分配Receiver角色。 - Invoker(发动者)
该角色是开始执行命令的角色,它会调用在Command角色中定义的接口(API)。
类图
由类图可知
- Invoker通过Command接口聚合了ConcreteCommand,在ConcreteCommand中又聚合Receiver
- Invoker调用ConcreteCommand中的execute方法发出命令,ConcreteCommand再调用Receiver的action方法接受命
举例
//Invoker和Client角色
public class Main extends JFrame implements ActionListener, MouseMotionListener,WindowListener {
private MacroCommand history = new MacroCommand();
private DrawCanvas canvas = new DrawCanvas(400,400,history);
private JButton clearButton = new JButton("clear");
public Main(String title){
super(title);
this.addWindowListener(this);
canvas.addMouseMotionListener(this);
clearButton.addActionListener(this);
Box buttonBox = new Box(BoxLayout.X_AXIS);
buttonBox.add(clearButton);
Box mainBox = new Box(BoxLayout.Y_AXIS);
mainBox.add(buttonBox);
mainBox.add(canvas);
getContentPane().add(mainBox);
pack();
show();
}
public void actionPerformed(ActionEvent e){
if(e.getSource() == clearButton){
history.clear();
canvas.repaint();
}
}
public void mouseMoved(MouseEvent e){
}
public void mouseDragged(MouseEvent e){
Command cmd = new DrawCommand(canvas,e.getPoint());
history.append(cmd);
cmd.execute();
}
public void windowClosing(WindowEvent e){
System.exit(0);
}
public void windowActivated(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowDeactivated(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
public static void main(String[] args){
new Main("Command Pattern Sample");
}
}
//Command
interface Command{
void execute();
};
//ConcreteCommand
class MacroCommand implements Command{
//命令的集合
private Stack commands = new Stack();
public void execute(){
Iterator it = commands.iterator();
while(it.hasNext()){
((Command)it.next()).execute();
}
}
//添加命令
public void append(Command cmd){
if(cmd != this){
commands.push(cmd);
}
}
//删除最后一条命令
public void clear(){
commands.clear();
}
}
//ConcreteCommand角色
class DrawCommand implements Command{
//绘制对象
protected Drawable drawable;
//绘制位置
protected Point position;
public DrawCommand(Drawable drawable,Point position){
this.drawable = drawable;
this.position = position;
}
public void execute(){
drawable.draw(position.x,position.y);
}
}
interface Drawable{
void draw(int x,int y);
}
//Receiver角色
class DrawCanvas extends Canvas implements Drawable{
private Color color = Color.red;
private int radius = 6;
private MacroCommand history;
public DrawCanvas(int width,int height,MacroCommand history){
setSize(width,height);
setBackground(Color.white);
this.history = history;
}
public void paint(Graphics g){
history.execute();
}
public void draw(int x,int y){
Graphics g = getGraphics();
g.setColor(color);
g.fillOval(x-radius,y-radius,radius*2,radius*2);
}
}
总结
- 符合开闭原则
- 实现行为请求者-行为实现者之间的解耦