In this third installment, we’ll cover Memento, Command, Visitor, Chain of Responsibility, and Mediator patterns. These patterns address construction, behavioral, and structural challenges, showcasing Kotlin’s expressive syntax and modern features.
1. Memento Pattern
The Memento Pattern captures and restores an object’s state without exposing its internal details.
interfaceCommand{funexecute()}classLight{funon()=println("Light is ON")funoff()=println("Light is OFF")}classLightOnCommand(privatevallight:Light):Command{overridefunexecute()=light.on()}classLightOffCommand(privatevallight:Light):Command{overridefunexecute()=light.off()}funmain(){vallight=Light()valcommands=listOf(LightOnCommand(light),LightOffCommand(light))commands.forEach{it.execute()}}
Why Kotlin?
Kotlin’s functional approach can further simplify command execution.
3. Visitor Pattern
The Visitor Pattern separates an algorithm from the object structure it operates on by moving the algorithm into a visitor object.
When to Use
When you need to perform operations across a set of objects with varying types.
interfaceShape{funaccept(visitor:ShapeVisitor)}classCircle(valradius:Double):Shape{overridefunaccept(visitor:ShapeVisitor){visitor.visit(this)}}classRectangle(valwidth:Double,valheight:Double):Shape{overridefunaccept(visitor:ShapeVisitor){visitor.visit(this)}}funinterfaceShapeVisitor{funvisit(shape:Shape)}funmain(){valshapes:List<Shape>=listOf(Circle(5.0),Rectangle(4.0,6.0))valvisitor=ShapeVisitor{shape->when(shape){isCircle->println("Circle with radius ${shape.radius}")isRectangle->println("Rectangle with width ${shape.width} and height ${shape.height}")}}shapes.forEach{it.accept(visitor)}}
Why Kotlin?
Kotlin’s fun interface and sealed classes streamline the visitor implementation.
4. Chain of Responsibility Pattern
The Chain of Responsibility Pattern passes a request along a chain of handlers until one processes it.
When to Use
When multiple objects can handle a request, and the handler isn’t determined until runtime.
classMediator{privatevalcolleagues=mutableListOf<Colleague>()funaddColleague(colleague:Colleague){colleagues.add(colleague)}funbroadcast(sender:Colleague,message:String){colleagues.filter{it!=sender}.forEach{it.receive(message)}}}interfaceColleague{funsend(message:String)funreceive(message:String)}classConcreteColleague(privatevalmediator:Mediator):Colleague{overridefunsend(message:String){println("Sending message: $message")mediator.broadcast(this,message)}overridefunreceive(message:String){println("Received message: $message")}}funmain(){valmediator=Mediator()valcolleague1=ConcreteColleague(mediator)valcolleague2=ConcreteColleague(mediator)mediator.addColleague(colleague1)mediator.addColleague(colleague2)colleague1.send("Hello from Colleague 1")}
Why Kotlin?
Kotlin’s first-class functions and collections simplify broadcasting and interaction.
Conclusion
These patterns—Memento, Command, Visitor, Chain of Responsibility, and Mediator—demonstrate Kotlin’s ability to enhance classic design patterns with modern features.
Which of these patterns do you find most interesting? Let me know! 🚀