Navigation

Related Articles

Back to Latest Articles

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

Tutorial on composite design pattern with code example In Kotlin


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

Kotlin

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

A Proxy design pattern is a structural design pattern. the idea behind is to make a proxy object that is capable of performing tasks similar to the original object. The need for...

Posted on by Baraa Abuzaid
Object Oriented Design

Understanding UML Class Diagram “The Fastest Approach…”

Understanding UML Diagram might be quite daunting task especially for those of Us whose not coming from formal CS background, you see all of these square boxes and different type...

Posted on by Baraa Abuzaid