Composite Pattern

The Composite Pattern, also known as the part-whole pattern, is used to treat a group of similar objects as a single object. It is usually based on a tree structure to combine objects, representing both part and whole hierarchy. This type of design pattern belongs to the structural pattern, which creates a tree-like structure of object groups.

Description

In software engineering, the composite pattern is a partitioning design pattern that describes treating a group of objects in the same way as a single instance of an object. The purpose of composition is to structure objects into a tree hierarchy to represent the entire structure of the part. In other words, it combines objects into a tree structure to represent the part-whole hierarchy, providing uniform usage of individual objects and composite objects, commonly used in managing tree menus, files, folders, and forms.

Advantages

  • Simple invocation for high-level modules.
  • Flexibility in adding nodes.
  • Consistent interface for using composite and individual objects.

Disadvantages

  • It is impossible to distinguish the interface of leaf objects, only discernible at runtime.
  • Excessive creation of wrapper objects leads to additional memory burden.
  • When using the composite pattern, the declarations of leaf and branch are implemented classes instead of interfaces, violating the Dependency Inversion Principle.

Implementation

class Folder { // Directory
    constructor(name) {
        this.name = name;
        this.nodes = [];
    }

    add(node) {
        this.nodes.push(node);
    }

    scan() {
        for (let node of this.nodes) {
            if(node instanceof Folder) node.scan();
            else node.getFile();
        }
    }
}

class File { // File
    constructor(name) {
        this.name = name;
    }

    add(file) {
        throw new Error("File nodes are leaf nodes");
    }

    getFile() {
        console.log("File:", this.name);
    }
}

(function(){
    var mediaFolder = new Folder("media");
    var movieFolder = new Folder("movie");
    var musicFolder = new Folder("music");

    var music = new File("./music.mp3");
    var moive = new File("./movie.mp4");

    mediaFolder.add(movieFolder);
    mediaFolder.add(musicFolder);
    musicFolder.add(music);
    movieFolder.add(moive);
    mediaFolder.scan(); // File: ./movie.mp4 File: ./music.mp3
})();

Daily Question

https://github.com/WindrunnerMax/EveryDay

Reference

- https://www.jianshu.com/p/a6e236040505 - https://segmentfault.com/a/1190000019773556 - https://github.com/tcorral/Design-Patterns-in-Javascript - https://www.runoob.com/design-pattern/composite-pattern.html - https://www.cnblogs.com/TomXu/archive/2012/04/12/2435530.html - https://github.com/sohamkamani/javascript-design-patterns-for-humans#-composite - https://xhui.top/2018/12/20/JS%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-8-%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F/