The GoF (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides) book describes this pattern as a pattern that "Allow you to compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. "
Now, let's
identify the composite pattern objects:
Base Component - This is the interface/abstract class for all
objects in the composition and contains some methods common to all the objects.
Leaf - This implements the base component in order to define the
behaviors/actions for the elements in the composition.
Composite - It consists of leaf elements and implements the operations
in base component.
In order to
exemplify the composite pattern let's suppose that we have a car dye house and
each day we prepare the cars that will be painted with a certain color (e.g. one
day, we have 3 Logan, 1 Mazda and 5 Volvo that should be painted red). Now,
let's put this scenario in code lines with respect for the composite pattern.
Next, we
will implement the composite pattern for our scenario using Java plain code.
Afterwards, we will adjust this code to obtain a JSF+CDI implementation.
Implement Base Component
Base component defines the common
methods for leaf and composites. In our case, the base
component is the car itself - this represents the abstract notion that should
be shaped in leaf objects. The common
method is represented by the fact that all cars will be painted:
public
interface Car {
public void paint(String color);
}
Implement Leaf Objects
Leaf implements base component (e.g. paint() method) and these are the building
block for the
composite. Below we define three leaf objects, but you can define as much
as needed:
// leaf
Logan
public class
Logan implements
Car {
@Override
public void
paint(String color) {
System.out.println("Logan (" + this
+ ") paint color: " + color);
}
}
// leaf Volvo
public class
Volvo implements
Car {
@Override
public void
paint(String color) {
System.out.println("Volvo (" + this
+ ") paint color: " + color);
}
}
// leaf Mazda
public class
Mazda implements
Car {
@Override
public void
paint(String color) {
System.out.println("Volvo (" + this
+ ") paint color: " + color);
}
}
Implement Composite
The composite object contains group of leaf objects and some helper methods (e.g.
for adding/removing leaf objects from
the group):
public class
PaintCar implements
Car {
//collection of cars
private List<Car> cars = new
ArrayList<>();
@Override
public void paint(String color) {
System.out.println("Color: " + color);
for (Car car : cars) {
car.paint(color);
}
}
// helper methods
//adding car
public void add(Car car) {
System.out.println("Adding car: " +
car);
this.cars.add(car);
}
//removing car
public void remove(Car car) {
System.out.println("Removing car: "
+ car);
this.cars.remove(car);
}
//removing all the cars
public void clear() {
System.out.println("Clearing all the
cars!");
this.cars.clear();
}
}
Note:
The composite also implements base component and acts as a leaf, only that it can contain group of leaf objects.
Testing
We can
easily perform a test as below:
Volvo v1 =
new Volvo();
Volvo v2 =
new Volvo();
Logan l1 =
new Logan();
Mazda m1 =
new Mazda();
PaintCar
paintCar = new PaintCar();
paintCar.add(v1);
paintCar.add(v2);
paintCar.add(l1);
paintCar.add(m1);
paintCar.paint("red");
The output
will be like this:
Volvo (1263027062)
paint color: red
Volvo (627550844)
paint color: red
Logan (1763318157)
paint color: red
Mazda (1869059866)
paint color: red
In part two
of this post, we will re-write this example in JSF+CDI style.
Niciun comentariu :
Trimiteți un comentariu