@rkenmi - Composite Pattern

Composite Pattern


Applying composite patterns

Composite Pattern


Back to Top

Updated on January 13, 2020

The Composition design pattern helps you unify individual objects and nested objects.

Here is one use case for the composition design pattern.

Meet Frank

A man named F. Frank decides to write an autobiography of himself. His book is rather strange; he writes a few chapter in the book that consists of subsections, kind of like a textbook. But Frank acknowledges that he himself is a strange guy, and he wants to sell the book as it is.

He calls the book "The Autobiography of F. Frank".
This is what he has so far on his book's table of contents:

  • Preface
  • Introduction
  • Chapter 1: Friends
    • Pink Guy
    • Dade
  • Chapter 2: Enemies
  • Chapter 3: Trials and Tribulations
    • Frank faces the dark lord
    • Training in the mountains
      • Fiesta
    • Warzone

Note how Chapter 2 doesn't have any sub-chapters, and Chapter 3's sub-chapter "Training in the mountains" has a mini-chapter. What is Frank thinking? Who knows.

Moving on, Frank decides that he wants his table of contents publicized on the world wide web, with detailed synopses of each chapter. He looks up some object oriented design ideas on the web and starts with the following.

class Entry(object):  
    """
        An entry in the table of contents
    """
    def __init__(self, name, summary):
        self.name = name
        self.summary = summary

class Chapter(Entry):  
    subchapters = []

    def add_subchapter(self, subchapter):
        self.subchapters.append(subchapter)


class ChapterTitle(Entry):  
    pass

Here, we see 3 classes. We have an Entry class, that represents each entry in the table of contents.

Next, we see the Chapter class and the ChapterTitle class.

Why did Frank define both Chapter and ChapterTitle to be classes that inherit from Entry? Chapter and ChapterTitle sounds awfully similar to each other, but Frank disagrees. Frank's reasoning is as follows:

F. Frank: "The Chapter class can have 1 or more Chapter Titles or Chapters. Yeah, you know, it's like that movie, Inception."

So, according to what Frank says, we can visualize his table of contents in this manner:

  • Preface (ChapterTitle)
  • Introduction (ChapterTitle)
  • Chapter 1: Friends (Chapter)
    • Pink Guy (ChapterTitle)
    • Dade (ChapterTitle)
  • Chapter 2: Enemies (ChapterTitle)
  • Chapter 3: Trials and Tribulations (Chapter)
    • Frank faces the dark lord (ChapterTitle)
    • Training in the mountains (Chapter)
      • Fiesta (ChapterTitle)
    • Warzone (ChapterTitle)

Note how Chapter 1 and Chapter 3 is a different class compared to Chapter 2. Chapter 3 also has a nested Chapter (a Chapter in a Chapter).

Composition

We can now see that the Chapter class is just a collection or aggregate of ChapterTitles.

Frank wants to design a class now, called TableOfContents that houses a list of Chapter objects or ChapterTitle objects. But storing a list of entries isn't enough; Frank wants the TableOfContents class to be smart enough to know how to handle a Chapter or a ChapterTitle when needed. Maybe a print_contents() method can be defined, which iterates over all of the entries, regardless of what class it is (why should it matter if it's a Chapter or a ChapterTitle, a Table of Contents class should print every entry there is!).

...

And it came to Frank right then and there. The design pattern he wants to use is the Composite pattern.

Definition

Directly from Wikipedia:

The composite pattern describes a group of objects that is treated the same way as a single instance of the same type of object.

The Composite pattern is basically used to represent objects like a tree (in particular, a computer science tree).

In a tree, there is a root node, and each child can also be a tree itself. On one hand, a child node with no offsprings is a leaf, which is identical to ChapterTitle. On another hand, a child node with several offsprings (a child with children) is basically another tree, which is identical to Chapter.

It then follows that the Chapter class is recursive in nature because it can have a child that is a Chapter itself, or a ChapterTitle.

When to use

Composite should be used when clients ignore the difference between compositions of objects and individual objects. If programmers find that they are using multiple objects in the same way, and often have nearly identical code to handle each of them, then composite is a good choice.


Article Tags:
composite patterndesign patternPython