Published on

Learning Design Patterns: Composite Pattern - The 100-Knot Bamboo Tree

Authors

The Composite Pattern is a clever design pattern that guides us on how to organize data in an intuitive and manageable way. Instead of dealing with individual objects, we group similar objects together, creating a flexible hierarchical structure. This helps make the program or module cleaner, easier to maintain, and more extensible.

Problem Statement - The Legend of the Hundred-Knot Bamboo Tree

We've all heard the story of the Hundred-Knot Bamboo Tree. A farmer was granted a magic spell by the Buddha to create a Hundred-Knot Bamboo Tree to marry the rich man's daughter. Little did anyone know that 2000 years later, a world-famous programming technique would be based on the idea of ​​the spell "Stick Together, Stick Together, Come Apart, Come Apart," which is the Composite Pattern.

Simulating Stick Together, Come Apart with Code

The Composite Pattern ideology advises us to build a structure for managing objects according to a specific data structure: it can be a Tree, List, or Set, Map. Like arranging the "Bamboo Knots" on the "Hundred-Knot Bamboo Tree". In this structure, there are two main types of objects:

  • Component (Bamboo Knot): Is the representation of a bamboo knot, nothing more, nothing less.
  • Composite (Bamboo Tree): Is the representation of a collection of many bamboo knots, which can be arranged in order to create a Hundred-Knot Bamboo Tree.
interface Component {
    fun subCount(): Int
    fun addSub(comp: Component)
    fun removeSub(comp: Component)
    fun clear()
}

class BambooNode() : Component {
    override fun subCount(): Int {
        return 1
    }
    override fun addSub(comp: Component) = Unit
    override fun removeSub(comp: Component) = Unit
    override fun clear() = Unit
}

class BambooTree(private val name: String) : Component {
    private val bambooNodes = mutableListOf()

    override fun subCount(): Int {
        return bambooNodes.map{ it.subCount() }.sum()
    }

    override fun addSub(comp: Component) {
        bambooNodes.add(comp)
    }

    override fun removeSub(comp: Component) {
        bambooNodes.remove(comp)
    }
    override fun clear() {
      bambooNodes.clear()
    }
}

fun main() {
    val cayTreTramDot = BambooTree("Cay Tre Tram Dot")
    khacNhapKhacNhap(cayTreTramDot)
    println(cayTreTramDot)
    khacXuatKhacXuat(cayTreTramDot)
    println(cayTreTramDot)
}
fun khacNhapKhacNhap(bambooTree: BambooTree) {
  for(i in 0..100) {
    bambooTree.addSub(BambooNode())
  }
}
fun khacXuatKhacXuat(bambooTree: BambooTree) {
  bambooTree.clear()
}

Lessons Learned From Composite Pattern

The Composite Pattern is not just a programming technique, but also a flexible mindset that requires us to creatively apply the most complex data structures.

More importantly, the Composite Pattern is also a method to help us systematize accumulated knowledge and experience.

Like building a Hundred-Knot Bamboo Tree with scientifically arranged Knots, the Composite Pattern helps us organize knowledge and experience into compact, easy-to-understand, and easy-to-retrieve Knots. When needed, we simply Stick Together these Knots, creating a solid Bamboo Tree of Knowledge, helping us make quick and effective decisions in this rapidly changing technological era.

Apply the Composite Pattern not only to create Hundred-Knot Bamboo Trees in your code into solid and easy-to-maintain projects, but also to build a system of knowledge and experience to be ready for any difficulties!

@dantech wish you success!