4.4 The Composite Pattern
The Composite pattern allows us to treat single objects or collections of objects in the same way, without knowing beforehand whether the node we are interacting with is a leaf node or a container. Let's take a deeper look at the Composite pattern in this lesson.
1.Introduction2 lessons, 09:16
2.Creational Design Patterns1 lesson, 09:14
3.Behavioural Patterns6 lessons, 1:11:30
4.Structural Patterns5 lessons, 38:41
5.Conclusion1 lesson, 01:43
4.4 The Composite Pattern
Hiya folks. In this lesson we're going to take a look at the composite pattern. The composite pattern is used in order to treat single objects or collections of objects in the same way. A great example of the composite pattern is how in J Query many methods are called on objects that may contain a single element on the page or multiple elements. We don't need to know beforehand. Compositions are used to create nested structures of nodes, where a node may be a single node known as a leaf node or a container of one or more single nodes like the visual representation of files and folders in a file system. The ability to iterate through the composite starting from any node and traversing up the tree is usually implicit. In our example for today's lesson, let's use the composite pattern to build a simple family tree. The tree will be a composite built from people objects. Children with no descendents of the leaf nodes whereas children with other children are the containers. So let's get started. We can create a new folder called Composite. And then inside this let's create a new module called Node. Inside this module, let's create a simple constructor called Person. The constructor accepts a name argument and sets this as an un property called name, each node also has a children property which starts out as an empty array, and a parent property that starts out with a null value. Now let's add some prototype methods. The add child method accepts a node and pushes this into the object's children property. We can also create a reciprocal link by setting the current object as the parent of the child passed to the method. This will be useful for allowing us to traverse both up or down the tree. Now we can add a method to traverse up. This method does not need to receive any arguments, so first of all we need to check with the current object has a parent object. And if it does we can just add a simple log message. And we'll then want to invoke the traverse up method of the parent. If there are no parents, we know that this is the root node. Now let's add a traverse down method. Again this method receives no arguments. First of all we need to check whether there are children. If there are we need to iterate through the children collection. We should also set the context for the for each method so that inside the handler this still refers to the current person object. And inside let's just add a simple log message first of all once again. And again, we need to invoke the traverse down method on the child. If there are no children, we know that it's a leaf node. So that's our base class sorted. We can now create a composite in the init module for this example. Before we do that, however, let's just update the main file to load the new init file. Now is at the init module. So first of all, we need to load our node class. And then we can create some nodes. All nodes are created in the exact same way. There is nothing special happening to differentiate leaf nodes from container nodes. So now we can build the tree. The root node can have two direct child nodes. We can make child one leaf node by not adding any child nodes to it, so let's just add some child nodes to child two. Child three can also be a leaf node. But, we can add a child to child four to make it a container node. And let's make child five a container node as well. We're out of nodes now so child six will be the deepest leaf node. At this point we can start our own node and try to traverse down. If we start at the root node, we should see the entire tree. So let's view the example in our browser now and just see if everything is wired up correctly. Looks like there's an issue in the init module. Let's just take a look. And it looks like I've forgotten to return the person constructor. So let's just do that quickly. So let's go back to the browser now. So it's saying child six is not defined. Let's take a look. And it isn't. Let's just fix that. And let's try again. And this time we see the entire tree. If we try to traverse down from a leaf node, we'll just see a message that the node is a leaf. If we want, we can start out at leaf node and traverse up through the tree. But if we start at the root node we'll just see a message that the root is the root. So in this lesson we looked at the composite pattern and saw that its main purpose is to allow single objects and collections of objects to be treated in the same way. As we found in our tree example we don't need to note beforehand whether we're dealing with a container node or a leaf node, we can still invoke the same methods on both leafs and containers without causing any errors. Thanks for watching.