Navigation

Related Articles

Back to Latest Articles
A Complete Guide To Design Patterns In Kotlin: Composite Design Pattern

A Complete Guide To Design Patterns In Kotlin: Composite Design Pattern

Tutorial on composite design pattern with code example In Kotlin


Baraa Abuzaid
Baraa Abuzaid
@baraaabuzaid
A Complete Guide To Design Patterns In...

A composite design pattern is built upon two principles in object-oriented programming. First, decomposition by breaking a whole into parts. Then generalization which generalizing multiple objects and abstract them into classes that have similar behaviors.
In the composite pattern, we have objects of different types. one object could be composed by another object in a tree-like manner. However, all the objects adhere to a supertype an interface or an abstract class. And that ensures a uniformity when dealing with these objects.
The uniformity is a key here which allows you to deal with these composite object without having to check for the type. I think a UML class diagram for the composite pattern will make it clear. More about UML  class diagram can be found here, in the UML class diagram focused article

 

From the UML class diagram, we see that we have two classes a Composite class and a Leaf class and both are implementing the same interface. Whereas, the composite class also contains an aggregate of IComponent class, this could be a list of type IComponent.

A practical example for the composite pattern could be implemented in a movie player. where you could have PlayList class and Movie class both are having same behaviors like play() getName() displaySubtitle() setPlaySpeed(). Furthermore, we could let both classes implement a IMedia interface. In this case Movie class will be the leaf class and PlayList is a composite class, hence it could be composed of a movie or another playlist. Thus, the UML class diagram will be like

And now what’s left is to implement the above example that shows the composite design pattern into a Kotlin code.

interface IMedia {
    fun play()
    fun displaySubtitle()
    fun setPlaySpeed(speed:Float)
    fun getName() :String
}

class Movie(val title:String):IMedia {
    private var speed = 1f

    override fun play() {
        println("Now playing: ${title}...")
    }

    override fun displaySubtitle() {
        println("display subtitle")
    }

    override fun setPlaySpeed(speed:Float) {
        this.speed = speed
        println("current play speed set to: $speed")
    }

    override fun getName(): String {
        return title
    }
}

class PlayList(val title:String):IMedia {
    var movieList:MutableList<IMedia> = mutableListOf()

    fun addNewMedia(media:IMedia) = movieList.add(media)
    fun removeMedia(media: IMedia){
        movieList = movieList.filter{ it.getName() != media.getName() }.toMutableList()
    }

    override fun play() {
        movieList.forEach { it.play() }
    }

    override fun displaySubtitle() {
        println("display certain subtitle")
    }

    override fun setPlaySpeed(speed: Float) {
        movieList.forEach { it.setPlaySpeed(speed) }
    }

    override fun getName(): String {
        return title
    }
}




fun main(args:Array<String>){
    val actionMoviePlayList:PlayList = PlayList("Action Movies")
    val movieB:IMedia = Movie("The Dark Knight")
    val movieC:IMedia = Movie("Inception")
    val movieD:IMedia = Movie("The Matrix")

    actionMoviePlayList.apply {
        addNewMedia(movieB)
        addNewMedia(movieC)
        addNewMedia(movieD)
    }

    val dramaPlayList:PlayList = PlayList("Drama Play List")
    val movie1:IMedia = Movie("The Godfather")
    val movie2:IMedia = Movie("The Shawshank Redemption")
    dramaPlayList.apply { addNewMedia(movie1);addNewMedia(movie2) }

    val myPlayList:PlayList = PlayList("My Play List")
    myPlayList.apply {
        addNewMedia(actionMoviePlayList)
        addNewMedia(dramaPlayList)
    }

    myPlayList.play()

}

 

 

 

featured photo by Kelvin Zyteng

Show Comments (0)

Comments

Related Articles

A Complete Guide To Design Patterns: Façade Design Pattern
Object Oriented Design

A Complete Guide To Design Patterns: Façade Design Pattern

  The Façade design pattern is a structural design pattern. It reduces coupling and improves code readability. you are very likely to use the Façade pattern when you would...

Posted on by Baraa Abuzaid
A Complete Guide To Design Patterns: The Adapter Design Pattern
Object Oriented Design

A Complete Guide To Design Patterns: The Adapter Design Pattern

The adapter design pattern is a structural design pattern. As the name drove from the adapter in the physical world, the adapter design pattern work in a similar way. In many...

Posted on by Baraa Abuzaid