The Command pattern is a widely-used design pattern that separates the execution of a command from its invocation. It is particularly useful when we need to encapsulate the request, parameters, and execution details of a particular operation.
The Composite pattern, on the other hand, is a design pattern that allows you to compose objects into tree structures to represent part-whole hierarchies.
When used together, the Command pattern and Composite pattern can create complex commands that can execute a set of sub-commands in a structured manner. This is particularly useful when there is a need to execute a command that involves multiple sub-commands that need to be executed in a particular order, or when we want to treat a group of commands as a single command.
To implement complex commands using the Command and Composite pattern, we can create a composite command object that uses the Command pattern to define each individual sub-command. The composite object can then execute the individual commands in a predetermined order.
Let’s consider an example to illustrate this concept. Suppose we have a drawing program that allows users to draw shapes on a canvas. Each shape is represented as a separate object with its own set of properties such as size, location, and color. We want to create a composite command that allows us to draw a complex shape that is composed of multiple sub-shapes.
First, we would create an interface for the Command pattern to define the structure of individual commands. In our case, we can define a ‘Drawable‘ interface with a ‘draw‘ method that takes a ‘Canvas‘ object as a parameter:
public interface Drawable {
void draw(Canvas canvas);
}
Next, we can create implementations of the ‘Drawable‘ interface for each of the sub-shapes that make up our complex shape. For example, we can create a ‘Rectangle‘ class that draws a rectangle on the canvas:
public class Rectangle implements Drawable {
private int x;
private int y;
private int width;
private int height;
private Color color;
public Rectangle(int x, int y, int width, int height, Color color) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
}
@Override
public void draw(Canvas canvas) {
canvas.drawRect(x, y, width, height, color);
}
}
Similarly, we can create a ‘Circle‘ class that draws a circle on the canvas:
public class Circle implements Drawable {
private int x;
private int y;
private int radius;
private Color color;
public Circle(int x, int y, int radius, Color color) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
}
@Override
public void draw(Canvas canvas) {
canvas.drawCircle(x, y, radius, color);
}
}
Now that we have defined our individual commands, we can use the Composite pattern to define a complex command that is composed of multiple sub-commands. We can create a ‘ComplexShape‘ class that holds a list of ‘Drawable‘ objects and can execute each of them in the order that they were added.
public class ComplexShape implements Drawable {
private List<Drawable> shapes = new ArrayList<>();
public void addShape(Drawable shape) {
shapes.add(shape);
}
@Override
public void draw(Canvas canvas) {
for (Drawable shape : shapes) {
shape.draw(canvas);
}
}
}
Finally, we can use our composite ‘ComplexShape‘ command just like any other ‘Drawable‘ command. For example, we can create a new ‘Canvas‘ object and add a ‘ComplexShape‘ that is composed of a ‘Rectangle‘ and a ‘Circle‘:
Canvas canvas = new Canvas();
ComplexShape complexShape = new ComplexShape();
complexShape.addShape(new Rectangle(10, 10, 100, 50, Color.RED));
complexShape.addShape(new Circle(50, 50, 25, Color.BLUE));
canvas.draw(complexShape);
This code will draw a complex shape that consists of a red rectangle and a blue circle on the canvas.
In conclusion, the Command and Composite patterns can be used together to create complex commands that execute a set of sub-commands in a structured manner. The Command pattern provides a way to encapsulate individual commands, while the Composite pattern provides a way to compose multiple commands into a single complex command.