读书笔记 仅供参考
简述
Command 模式是使用表示命令的类来代替方法的调用,这样就可以管理工作的历史记录。
角色和 UML
Command
定义命令的接口(API)。
ConcreteCommand
负责实现在 Command 角色中定义的接口(API)。
Receiver
是 Command 角色执行命令时的对象,可以称为命令接收者。
Client
负责生成 ConcreteCommand 角色并分配 Receiver 角色。
Invoker
是开始执行命令的角色,会调用 Command 角色中定义的接口(API)。
UML
例子
例程是一个简单的画图程序,随着鼠标点击拖拽,可以进行绘画,每一个点的绘画就是一个 Command。可以将之前的 Command 保存下来,以供之后的重绘使用,或者实现 undo 需求。
// Command 角色,只需要定义一个方法
public interface Command {
void execute();
}
// 表示绘制对象的接口,也是 Receiver 角色
public interface Drawable {
void draw(int x, int y);
}
// 绘制一个点的命令
public class DrawCommand implements Command {
// 绘制对象
protected Drawable drawable;
//绘制位置
private Point position;
public DrawCommand(Drawable drawable, Point position) {
this.drawable = drawable;
this.position = position;
}
@Override
public void execute() {
drawable.draw(position.x, position.y);
}
}
//由多条命令整合的命令
public class MacroCommand implements Command {
//命令的集合
private Stack<Command> commands = new Stack<>();
@Override
public void execute() {
Iterator<Command> it = commands.iterator();
while (it.hasNext()) {
it.next().execute();
}
}
//添加命令
public void append(Command command) {
if (command != this) {
commands.push(command);
}
}
//删除最后一条命令,达到撤销命令的目的
public void undo() {
if (!commands.empty()) {
commands.pop();
}
}
//删除所有命令
public void clear() {
commands.clear();
}
}
// 画板
public 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 graphics) {
history.execute();
}
@Override
public void draw(int x, int y) {
Graphics graphics = getGraphics();
graphics.setColor(color);
graphics.fillOval(x - radius, y - radius, radius * 2, radius * 2);
}
}
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) throws HeadlessException {
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 static void main(String[] args) {
new Main("Command Pattern Sample");
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == clearButton) {
history.clear();
canvas.repaint();
}
}
@Override
public void mouseDragged(MouseEvent e) {
Command cmd = new DrawCommand(canvas, e.getPoint());
history.append(cmd);
cmd.execute();
}
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
}