Sometimes you really want to operate a swarm of objects the exact same way that you’d operate a single instance of those objects. When the need arises, the Composite Pattern has you covered!
The Composite Pattern is quirky fun. It’s a way to control a slew of objects through single method calls. More specifically, it’s a way to control a slew of objects the same way that you’d control one of those objects.
That common interface provides a consistency that proves all manner of useful. But c’mon. It’s just fun making a bunch of things dance in unison, so let’s hop to it!
Consider, if you will, a simple drone. After adding it to a coordinate grid, it exists at the center of life. We can move it up. We can rotate it. We can move it left. It’s good fun.
But you know what’s more fun? A swarm of drones!
Now, we don’t have 25 hands to use 25 remotes to control a swarm of 25 drones. We want to treat the swarm the same way that we treat a
Drone. We want to create a swarm, add it to the grid, and then move the entire swarm in one operation. Rotate the entire swarm in one operation. And move it again in one operation.
Moreover, we want the same operations that we use with the single drone. The swarm should have move and rotate methods. And when called, these methods should move and rotate each drone within the swarm.
Since we want the swarm to respond to the same methods as the individual drone, we want both to implement the same interface. In the pattern, this interface is known as the “Component.” It’s the idea of the thing or things performing operations.
We’ve named our component “Flier.” It describes the idea of a drone or swarm of drones. A class implementing this idea should have an x-y position and should face in a direction. It should also be able to perform operations like moving up, down, left, right by some amount, and should be able to rotate clockwise and counter-clockwise.
Drone class implements this interface. It’s got the properties required by the interface. It can perform the operations required by the interface. The
Drone class represents a single thing that implements the
Flier / component idea. So it’s usually called a “leaf” in the pattern.
We’re going to build a composite class named “Swarm.” It’ll implement the same
Flier / component interface. So it needs to have the same
y properties. And the swarm needs to face in a direction.
The principle concept in the composite is that operation methods don’t operate so much on the composite object itself as they do on each item in the composite’s list of components. That is, the movement methods will move each individual drone comprising the swarm.
To see this in action, we first need… a list of drones. We’ll work with a 5×5 grid of drones that will operate in unison. The swarm constructor initializes the start position for the center of the swarm, defaulting to (0,0).
We’ll need a half count to position swarm drones around the center. Then loop over 5
x positions… And 5
y positions… Adding new drones to the swarm’s list, with each in their corresponding x-y position. With that, we have a 5×5 swarm of drones.
We’re not done with the composite yet. We need to define the operation methods. Again, these operation methods do their thing by sending the operation to each individual component. So, the
moveUp method tells each drone in the swarm to move up by the amount specified, defaulting to
1 grid point. The same goes for
moveRight(). The rotate methods also get the same treatment.
And that really is the fundamental idea of the Composite Pattern. An operation works through each component in the list and performs that same operation on each component.
This particular implementation isn’t quite ready. Our
Grid collaborator class, which provides the nice visual representation of the drones, knows how to add a single drone. We have to teach it how to add a swarm. When the
Flier / component being added is a
Drone, we continue to add it directly to the grid’s list of drones. When the
Flier is a
Swarm, however, we add all of the swarm’s drones to the grid.
Now we’re ready to play. We can create a new swarm and add it to the grid… which displays our 5×5 composite swarm at the center. Now for some composite operations. First, we can move up 5 and… each individual drone in the swarm moves up 5! We can rotate clockwise and… each drone component in the swarm rotates clockwise! And we can move right 3 and each item in the swarm composite moves right 3.
How much spooky fun is that? All those drones moving and spinning in unison is something to see!
The Composite is one of those “easy” patterns — something that we’d stumble into even without much programming experience. The uses of the pattern are many — and it’s often combined with other patterns. But the implications and consequences of applying it can be surprising for such an easy pattern.
We’ll have a good time with those in the upcoming episodes. But for now… dance flying robots. Dance!