Composite design pattern

Hierarchical objects with arbitrary depths can be used to represent using a composite pattern. The root object will treat the sub-objects and the unit component object as the same. The sub-objects can also be sometimes complex or an aggregation of several unit components.

An example is a directory structure, with each directory containing multiple other directories, files and so on. Represent a unit component, which is the FileObject, as a general interface.

interface FileObject {
    int getSize();
}

Both files and directories can be represented as a FileObject.

class File implements FileObject {

    ...
    private int size;

    @Override
    int getSize() {
        return this.size;
    }
    ...

}

class Directory implements FileObject {

    ...
    private int size;

    @Override
    int getSize() {
        return this.size;
    }
    ...

}

Using these components, the client, which in our case can be assumed to be a FileViewer, can get the size of any of the components.

class FileViewer {

    ...
    private List<FileObject> fileObjects;

    int getSize() {
        int totalSize = 0;
        for (FileObject fileObject: this.fileObjects) {
            totalSize += fileObject.getSize();
        }
    }
    ...
}

In addition to the getSize(), the FileObject interface can be expanded to other similar tasks, such as getName(), getPermissions(), etc. This allows the FileViewer to treat the individual components equally, irrespective of the fact that whether they are sub-directories or files.




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • Vendor lock-in Antipattern
  • Cut and Paste Programming Antipattern
  • Spaghetti Antipattern