Here is a summary of the ** Command pattern ** in the GoF design pattern.
--The English word Command means ** command **. --The Command pattern is a method of expressing an instance of a class that represents an instruction as one **. --If you want to manage the history of instructions, you can manage the collection of instances. If you save a collection of instructions, you can execute the same instruction or combine multiple instructions and reuse them as new instructions. --The GoF design patterns are classified as ** behavioral design patterns **.

This is a simple drawing program.
An interface that expresses instructions.
Command.java
package command;
public interface Command {
	public abstract void execute();
}
This class expresses "instructions that combine multiple instructions".
MacroCommand.java
package command;
import java.util.Iterator;
import java.util.Stack;
public class MacroCommand implements Command {
	//Set of instructions
	private Stack commands = new Stack();
	public void execute() {
		Iterator it = commands.iterator();
		while (it.hasNext()) {
			((Command) it.next()).execute();
		}
	}
	//add to
	public void append(Command cmd) {
		if (cmd != this) {
			commands.push(cmd);
		}
	}
	//Delete last instruction
	public void undo() {
		if (!commands.empty()) {
			commands.pop();
		}
	}
	//Delete all
	public void clear() {
		commands.clear();
	}
}
An interface that expresses the "drawing target".
Drawable.java
package drawer;
public interface Drawable {
	public abstract void draw(int x, int y);
}
It is a class that implements "drawing target".
DrawCanvas.java
package drawer;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import command.MacroCommand;
public class DrawCanvas extends Canvas implements Drawable {
	//Drawing color
	private Color color = Color.red;
	//Radius of points to draw
	private int radius = 6;
	//History
	private MacroCommand history;
	public DrawCanvas(int width, int height, MacroCommand history) {
		setSize(width, height);
		setBackground(Color.white);
		this.history = history;
	}
	//Redraw the entire history
	public void paint(Graphics g) {
		history.execute();
	}
	//drawing
	public void draw(int x, int y) {
		Graphics g = getGraphics();
		g.setColor(color);
		g.fillOval(x - radius, y - radius, radius * 2, radius * 2);
	}
}
This class expresses "point drawing command".
DrawCommand.java
package drawer;
import java.awt.Point;
import command.Command;
public class DrawCommand implements Command {
	//Drawing target
	protected Drawable drawable;
	//Drawing position
	private Point position;
	public DrawCommand(Drawable drawable, Point position) {
		this.drawable = drawable;
		this.position = position;
	}
	public void execute() {
		drawable.draw(position.x, position.y);
	}
}
This class performs the main processing.
Main.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import command.Command;
import command.MacroCommand;
import drawer.DrawCanvas;
import drawer.DrawCommand;
public class Main extends JFrame implements ActionListener, MouseMotionListener, WindowListener {
	//Drawing history
	private MacroCommand history = new MacroCommand();
	//Drawing area
	private DrawCanvas canvas = new DrawCanvas(400, 400, history);
	//Undo button
	private JButton undoButton = new JButton("undo");
	//Erase button
	private JButton clearButton = new JButton("clear");
	public Main(String title) {
		super(title);
		this.addWindowListener(this);
		canvas.addMouseMotionListener(this);
		undoButton.addActionListener(this);
		clearButton.addActionListener(this);
		Box buttonBox = new Box(BoxLayout.X_AXIS);
		buttonBox.add(undoButton);
		buttonBox.add(clearButton);
		Box mainBox = new Box(BoxLayout.Y_AXIS);
		mainBox.add(buttonBox);
		mainBox.add(canvas);
		getContentPane().add(mainBox);
		pack();
		show();
	}
	//For ActionListener
	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();
		if (source == undoButton) {
			history.undo();
			canvas.repaint();
		} else if (source == clearButton) {
			history.clear();
			canvas.repaint();
		}
	}
	//For MouseMotionListener
	public void mouseMoved(MouseEvent e) {
	}
	public void mouseDragged(MouseEvent e) {
		Command cmd = new DrawCommand(canvas, e.getPoint());
		history.append(cmd);
		cmd.execute();
	}
	//For WindowListener
	public void windowClosing(WindowEvent e) {
	}
	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");
	}
}

By expressing an "instruction" as an object, it is possible to keep a history of the instruction and re-execute the instruction. Also, if you want to add a new "instruction", you only need to create a class that implements the Command interface, which makes it easier to extend the functionality.
-** GoF design pattern summary **
This article and sample program were created based on the following books.
-** Introduction to design patterns learned in Java language **
It was very easy to understand and I learned a lot. Thank you. The detailed explanations of the design patterns and sample programs are written, so please take a look at the books as well.
Recommended Posts