Join Jungwoo Ryoo for an in-depth discussion in this video Composite example, part of Python: Design Patterns.
- Let's start by defining our Abstract class, which is Component. Nothing too much is done in the definition of the Component class except for defining our interface method, component_function. Now let's move on to the Child class definition. Since this one is inheriting from the Component class we'll have to say its parent is Component right here. And we'll have an attribute to store the name of the child.
So we'll simply say self.name, assignment args, the index is 0, so what we're doing here is we're simply getting an argument from the instantiation process of the Child class and the first argument is the one we're going to be using. And then the second method here is implementing the abstract method component_function. The implementation is simply printing the name of the child.
Let's move on to the Composite class and the Composite class is also inheriting from the abstract class Component, which is why we have to state Component here. We also need another attribute to store the name of the composite object. So self.name, assignment args, the index is 0, so we will be using the first argument to get the name of the composite object.
And then we have another attribute, which is a list that is going to be keeping all our child items in the composite object. Scroll down a little bit. And then the rest of the methods we're defining are mostly utility methods. For example, we have this method called append_child, which is simply used to add a new child. And we also have a remove_child method as you can see there. And then in our definition of the abstract method, component_function, we are first printing the name of the composite object, as you can see here.
And then the second thing we're doing is iterating through all the child objects and then invoking their component function printing their names. So now we're ready to go ahead and use these classes we just defined. Scroll down a little bit. So first we will be building a composite submenu, so it's not a top level menu, but it will used as a submenu, but it is a composite itself and has its own children, as you can see.
So we create the composite submenu here, and then we also create the child items, and then we simply add the child items to the composite submenu1. And now we're actually going to be doing some coding to create the top level composite menu here. So the variable name is top, assignment Composite is the class we're using, and it has an argument which is the name of the composite object, top_menu.
And then we'll build a plain, simple submenu, which is not a composite. So we'll call this sub2, assignment Child, because it's a child. And we'll name it submenu2. Now let's add the composite submenu1 to the top level composite menu by using the append_child method. Top.append_child, which is sub1.
And then next is adding the plain submenu2 to the top level composite menu. So we'll just say top.append_child, now sub2. Now all we have to do is to test if our composite pattern actually works by invoking this component_function on the composite object. So top.component_function, and we'll go to Tools and click on Build.
Oh, there is a small typo here, this C has to be an uppercase C, not lowercase, so that's a typo. Let's try it again and it works beautifully. As you can see this composite parent could be very useful, especially when you have a tree structure in which you could have a plain child item, as well as composite child items.
- Understanding design patterns
- Best design practices: consistency, completeness, and correctness
- Working with creational patterns
- Working with structural patterns
- Working with behavioral patterns
Skill Level Intermediate
Q: In the strategy pattern example, why does the code keep executing the default function rather than the alternate?
A: The programming demonstration skips the step of defining what the strategy pattern should be when an alternate function name is provided
as an argument as shown below.