Today I’ve been looking at the composite pattern, in order to use it in the project I’m currently working on. The composite pattern is mainly designed to create a uniform way to approach similar objects. Let’s start with a nice quote from the GOF :
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
What this basically means is that with the composite pattern we can create a tree-like structure of objects where every object can either be a leaf or a composite. This allows us to create a structure with an indefinite depth of objects. Let me just point out that there are 2 different implementations for this pattern but I will discuss both of them so you can decide which want you want to use.
Let’s start with the UML scheme for this pattern.
As you can see in the scheme we start with creating an interface for our composite pattern, which we will use in our client classes. By Using this interface we’re allowing ourselves to access our objects without actually knowing whether this object is a leaf or a composite in our structure. The basic idea is to add all generic methods to the interface so that you can access them in the client class by using the interface. The composite implementations should delegate all these generic methods to his child objects. This way we can traverse the tree and preform an operation on all components of our tree.
Let’s have a look at some code now. We will create a component pattern for shape objects. By using the composite pattern we can have drawings which have an infinite number of shapes. First of all we create an interface for our component pattern :
public interface Component {
public void draw();
public void growSize(int size);
public boolean isComposite();
}
As you can see we created an interface for our component pattern which defines the methods that apply to all components in our structure. Our next step would be to create the implementations of this interface, we’ll start with the leaf :
public class Circle Component {public void draw() {
// actual implementation of our draw
}
public void growSize(int size) {
// increase the diameter of our circle
}
public boolean isComposite() {
return false;
}
Next up is another implementation of the component, but this time it will be a composite :
public class Rectangle Component {
private List children = new ArrayList();public void draw() {
foreach(component comp : children) {
// actual implementation of our draw
}}
public void growSize(int size) {
foreach(component comp : children) {
// increase the diameter of our circle
}
}public List getChildren() {
return children;
}public void addChild(Component child) {
this.children.add(child);
}public void removeChild(Component child) {
this.children.remove(child);
}public boolean isComposite() {
return true;
}
}
Now, as I mentioned at the beginning of this post, there are 2 implementations of this pattern. As you might already noticed, we use a method called isComposite() to determine if this object is a leaf or a composite, because at some point in our client classes we will probably have to know whether or not the object has children in order to access them directly. This is where our implementations of the composite pattern differ. This implementation uses the isComposite() to determine if it’s a composite and then preforms a cast in order to use the getChildren() removeChild() and addChild(). The other implementation has those methods in the interface, so you will be able to call them at any component ( leaf and composite ), the main advantage is that we don’t have to do the the check and the cast, but on the other hand, we have to implement the methods in our leafs as-well, which will be methods that just throw an exception.
More information on this pattern can be found at javaworld or wikipedia.
5 Comments so far
Leave a comment
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Doménique,
A few remarks on your example:
As it is written here, a rectangle can be composed out of circles. That is remarkable. If it were lines, I would agree.
Secondly, in the explanation of the pattern, it is stated explicitly a few times that one of the goals of the Composite pattern is to make clients
unaware of the specific Leaf or Composite classes they’re using. This is to simplify your client code. It for this reason, by the way, that in the class diagram, a dependency line is drawn from the client to the component, and not to the leafs or composites! That is the point about this pattern.
By introducing a method isComposite() you are exactly doing the opposite : clients do know wheter they are dealing with a leaf or composite. It will complicate the client because there are more dependencies.
Comment by Geert Vandevenne May 16, 2007 @ 10:10I agree, that the example given here might be a little bit confusing, it would have been better with lines instead of circles :)
Comment by Tilleuil Doménique May 16, 2007 @ 10:10The isComposite() method here, is only used if you want to traverse your structure. You shouldn’t use it for anything else. The sole purpose of this method is to avoid the need of an instanceof check before casting your object to a composite or leaf. Although in most cases you wouldn’t want to get a specific instance from the structure, this method is only there to simplify your code if you do want to do this.
In any case, if you use the other implementation of this pattern mentioned above, there wouldn’t be a need to have this method, but I believe that creating methods in a parent class which don’t apply to the child are a violation of OO concepts.
You are correct about that, because in case you add Add and Remove methods in the Component class, which do not apply to the Leafs, you violate the substitutability principle : the subclass is not a-kind-of superclass object.
Comment by Geert Vandevenne May 16, 2007 @ 10:10The Gof also discusses this topic in the implementation section : according to them it’s a trade-off between safety and transparency. They choose for transparency, and provide a solution that looks more or less like yours.
I agree with you, the GOF book suggest to favor transparency over type-safety, but I don’t follow there opinion because throwing out UnsupportedMethodExceptions or null’s are not very clean in my opinion. :) But as you stated, it’s a trade-off and therefore you should decide on that for yourself.
Comment by Tilleuil Doménique May 16, 2007 @ 11:11sbecomingly buy cialis clone
Comment by Arronieni January 30, 2009 @ 13:13