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