SlideShare a Scribd company logo
Design
Patterns
with
Kotlin
Alexey Soshin, November 2018
Intro
● “Design Patterns” by “Gang of Four” was written back in ‘92. This is the only edition of the
book. All examples in the book are either in C++ or SmallTalk
● Somebody once said that “design patterns are workarounds for shortcomings of
particular language”. But he was fan of Lisp, so we can disregard that saying
● Disclaimer: all your favorite design patterns, including Singleton, will work in Kotlin as-is.
Still, there are often better ways to achieve the same goal
Singleton
“Ensure a class has only one instance, and provide a global point of access to it.”
public final class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
In Java:
volatile
synchronized
instance
static
private static
Singleton - continued
object Singleton
Taken directly from Scala
CounterSingleton.INSTANCE.increment();
When called from Java, instead of usual .getInstance() uses INSTANCE field
CounterSingleton.increment()
Very concise usage syntax:
In Kotlin:
Builder
“Allows constructing complex objects step by step”
ElasticSearch API, for example, just LOVES builders...
client.prepareSearch("documents")
.setQuery(query(dressQuery))
.addSort(RANK_SORT)
.addSort(SEARCHES_SORT)
.get()
Builder - continued
In Kotlin, often can be replaced with combination of default parameters and .apply()
function
data class Mail(val to: String,
var title: String = "",
var message: String = "",
var cc: List<String> = listOf(),
var bcc: List<String> = listOf(),
val attachments: List<java.io.File> = listOf()) {
fun message(m: String) = apply {
message = m
} // No need to "return this"
}
val mail = Mail("bill.gates@microsoft.com")
.message("How are you?").apply {
cc = listOf("s.ballmer@microsoft.com")
bcc = listOf("pichais@gmail.com")
}
Less boilerplate, same readability
Proxy
“Provides a substitute or placeholder for another object”
Decorator and Proxy have different purposes but
similar structures. Both describe how to provide a
level of indirection to another object, and the
implementations keep a reference to the object to
which they forward requests.
In Kotlin: by keyword is used for such delegation
val image: File by lazy {
println("Fetching image over network")
val f = File.createTempFile("cat", ".jpg")
URL(url).openStream().use {
it.copyTo(BufferedOutputStream(f.outputStream()))
}.also { println("Done fetching") }
f
}
Iterator
“Abstracts traversal of data structures in a linear way”
class MyDataStructure<T> implements Iterable<T> { ... }
In Java, this is built-in as Iterable interface
Same will work also in Kotlin
class MyDataStructure<T>: Iterable<T> { ... }
Iterator - continued
But in order not to have to implement too many interfaces (Android API, anyone?), you
can use iterator() function instead:
class MyDataStructure<T> {
operator fun iterator() = object: Iterator<T> {
override fun hasNext(): Boolean {
...
}
override fun next(): T {
...
}
}
}
State
“Allows an object to alter its behavior when its internal state changes”
sealed class Mood
object Still : Mood() //
class Aggressive(val madnessLevel: Int) : Mood()
object Retreating : Mood()
object Dead : Mood()
Kotlin sealed classes are great for state management
Since all descendants of a sealed class must reside in the same file, you also
avoid lots of small files describing states in your project
State - continued
Best feature is that compiler makes sure that you check all states when using
sealed class
override fun seeHero() {
mood = when(mood) {
is Still -> Aggressive(2)
is Aggressive -> Retreating
is Retreating -> Aggressive(1)
// Doesn't compile, when must be exhaustive
}
}
override fun seeHero() {
mood = when(mood) {
is Still -> Aggressive(2)
is Aggressive -> Retreating
is Retreating -> Aggressive(1)
is Dead -> Dead // Better
}
}
You must either specify all conditions, or use else block
Strategy
“Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets
the algorithm vary independently from the clients that use it.”
class OurHero {
private var direction = Direction.LEFT
private var x: Int = 42
private var y: Int = 173
// Strategy
var currentWeapon = Weapons.peashooter
val shoot = fun() {
currentWeapon(x, y, direction)
}
}
In Kotlin functions are first class citizens.
If you want to replace a method - replace a method, don’t talk.
Strategy - continued
object Weapons {
val peashooter = fun(x: Int, y: Int, direction: Direction) {
// Fly straight
}
val banana = fun(x: Int, y: Int, direction: Direction) {
// Return when you hit screen border
}
val pomegranate = fun(x: Int, y: Int, direction: Direction) {
// Explode when you hit first enemy
}
}
You can encapsulate all available strategies
And replace them at will
val h = OurHero()
h.shoot() // peashooter
h.currentWeapon = Weapons.banana
h.shoot() // banana
Deferred value
Not once I’ve heard JavaScript developers state that they don’t need design patterns in
JavaScript.
But Deferred value is one of the concurrent design patterns, and it’s widely used nowadays
Also called Future or Promise
with(GlobalScope) {
val userProfile: Deferred<String> = async {
delay(Random().nextInt(100).toLong())
"Profile"
}
}
val profile: String = userProfile.await()
In Kotlin provided as part of coroutines library:
Fan Out
“Deliver message to multiple destinations without halting the process”
Producer
Consumer 1 Consumer 2 Consumer 3
“r” “n” “d”
Used to distribute work
Each message delivered to only consumer,
semi-randomly
Kotlin coroutine library provides
ReceiveChannel for that purpose
fun CoroutineScope.producer(): ReceiveChannel<String> = produce {
for (i in 1..1_000_000) {
for (c in 'a' .. 'z') {
send(c.toString()) // produce next
}
}
}
Fan Out - continued
“Deliver message to multiple destinations without halting the process”
Consumers can iterate over the channel, until it’s closed
fun CoroutineScope.consumer(id: Int,
channel: ReceiveChannel<String>) = launch {
for (msg in channel) {
println("Processor #$id received $msg")
}
}
Here we distribute work between 4 consumers:
val producer = producer()
val processors = List(4) {
consumer(it, producer)
}
for (p in processors) {
p.join()
}
Fan In
Similar to Fan Out pattern, Fan In relies on coroutines library and channels
“Receive messages from multiple sources concurrently”
fun CoroutineScope.collector(): SendChannel<Int> = actor {
for (msg in channel) {
println("Got $msg")
}
}
Multiple producers are able to send to the same channel
fun CoroutineScope.producer(id: Int, channel: SendChannel<Int>) = launch {
repeat(10_000) {
channel.send(id)
}
}
Fan In - continued
val collector = collector()
val producers = List(4) {
producer(it, collector)
}
producers.forEach { it.join() }
Multiple producers are able to send to the same channel
Outputs:
...
Got 0
Got 0
Got 1
Got 2
Got 3
Got 0
Got 0
...
Summary
● Design patterns are everywhere
● Like any new language (unless it’s Go), Kotlin learns from shortcomings of its
predecessors
● Kotlin has a lot of design patterns built in, as either idioms, language constructs or
extension libraries
● Design patterns are not limited by GoF book
References
https://sourcemaking.com/design_patterns
https://refactoring.guru/design-patterns
Question time
Thanks a lot for attending!

More Related Content

PPTX
Design patterns with kotlin
PPTX
Design patterns with kotlin
PDF
Wrapper classes
PPS
Wrapper class
PDF
Why we cannot ignore Functional Programming
PPTX
Autoboxing And Unboxing In Java
PPTX
Java Static Factory Methods
PPTX
Lecture 2, c++(complete reference,herbet sheidt)chapter-12
Design patterns with kotlin
Design patterns with kotlin
Wrapper classes
Wrapper class
Why we cannot ignore Functional Programming
Autoboxing And Unboxing In Java
Java Static Factory Methods
Lecture 2, c++(complete reference,herbet sheidt)chapter-12

What's hot (20)

PDF
Kotlin, smarter development for the jvm
PDF
Kotlin hands on - MorningTech ekito 2017
PPTX
PPTX
คลาสและการเขียนโปรแกรมเชิงวัตถุเบื้องต้น
PDF
DOC
1183 c-interview-questions-and-answers
PPTX
Iterator - a powerful but underappreciated design pattern
PDF
Kotlin advanced - language reference for android developers
PPTX
Java fundamentals
PDF
Lazy java
DOC
Brief Summary Of C++
PPT
Iterator Design Pattern
PPS
String and string buffer
PPTX
Lecture 4.2 c++(comlete reference book)
PDF
Jumping-with-java8
DOCX
Autoboxing and unboxing
PPTX
Java vs kotlin
PDF
Implicit conversion and parameters
PPT
Oop Constructor Destructors Constructor Overloading lecture 2
PPTX
Kotlin – the future of android
Kotlin, smarter development for the jvm
Kotlin hands on - MorningTech ekito 2017
คลาสและการเขียนโปรแกรมเชิงวัตถุเบื้องต้น
1183 c-interview-questions-and-answers
Iterator - a powerful but underappreciated design pattern
Kotlin advanced - language reference for android developers
Java fundamentals
Lazy java
Brief Summary Of C++
Iterator Design Pattern
String and string buffer
Lecture 4.2 c++(comlete reference book)
Jumping-with-java8
Autoboxing and unboxing
Java vs kotlin
Implicit conversion and parameters
Oop Constructor Destructors Constructor Overloading lecture 2
Kotlin – the future of android
Ad

Similar to Design patterns with Kotlin (20)

PDF
What’s new in Kotlin?
PPTX
K is for Kotlin
PDF
Java design patterns
PDF
Container Classes
PDF
C++ Interview Question And Answer
PDF
C++ questions And Answer
PPTX
Exploring Kotlin language basics for Android App development
PPTX
Java For Automation
PDF
Kotlin Advanced - language reference for Android developers
PDF
Kotlin- Basic to Advance
ODP
Functional programming with Scala
DOCX
C# Unit 2 notes
PPTX
Chapter 2 OOP using C++ (Introduction).pptx
PDF
Kotlin for Android Developers - 3
PDF
Introductiontoprogramminginscala
PDF
Design patterns
PDF
Kotlin cheat sheet by ekito
PDF
Kotlin for Android - Vali Iorgu - mRready
PPTX
Oop lect3.pptx
PDF
Intro to Kotlin
What’s new in Kotlin?
K is for Kotlin
Java design patterns
Container Classes
C++ Interview Question And Answer
C++ questions And Answer
Exploring Kotlin language basics for Android App development
Java For Automation
Kotlin Advanced - language reference for Android developers
Kotlin- Basic to Advance
Functional programming with Scala
C# Unit 2 notes
Chapter 2 OOP using C++ (Introduction).pptx
Kotlin for Android Developers - 3
Introductiontoprogramminginscala
Design patterns
Kotlin cheat sheet by ekito
Kotlin for Android - Vali Iorgu - mRready
Oop lect3.pptx
Intro to Kotlin
Ad

Recently uploaded (20)

PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Understanding Forklifts - TECH EHS Solution
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
How Creative Agencies Leverage Project Management Software.pdf
PPTX
Transform Your Business with a Software ERP System
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PPTX
history of c programming in notes for students .pptx
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PPTX
L1 - Introduction to python Backend.pptx
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PPTX
Essential Infomation Tech presentation.pptx
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Understanding Forklifts - TECH EHS Solution
VVF-Customer-Presentation2025-Ver1.9.pptx
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Operating system designcfffgfgggggggvggggggggg
How Creative Agencies Leverage Project Management Software.pdf
Transform Your Business with a Software ERP System
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
history of c programming in notes for students .pptx
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
2025 Textile ERP Trends: SAP, Odoo & Oracle
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
L1 - Introduction to python Backend.pptx
How to Choose the Right IT Partner for Your Business in Malaysia
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
Odoo Companies in India – Driving Business Transformation.pdf
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Essential Infomation Tech presentation.pptx

Design patterns with Kotlin

  • 2. Intro ● “Design Patterns” by “Gang of Four” was written back in ‘92. This is the only edition of the book. All examples in the book are either in C++ or SmallTalk ● Somebody once said that “design patterns are workarounds for shortcomings of particular language”. But he was fan of Lisp, so we can disregard that saying ● Disclaimer: all your favorite design patterns, including Singleton, will work in Kotlin as-is. Still, there are often better ways to achieve the same goal
  • 3. Singleton “Ensure a class has only one instance, and provide a global point of access to it.” public final class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } } In Java: volatile synchronized instance static private static
  • 4. Singleton - continued object Singleton Taken directly from Scala CounterSingleton.INSTANCE.increment(); When called from Java, instead of usual .getInstance() uses INSTANCE field CounterSingleton.increment() Very concise usage syntax: In Kotlin:
  • 5. Builder “Allows constructing complex objects step by step” ElasticSearch API, for example, just LOVES builders... client.prepareSearch("documents") .setQuery(query(dressQuery)) .addSort(RANK_SORT) .addSort(SEARCHES_SORT) .get()
  • 6. Builder - continued In Kotlin, often can be replaced with combination of default parameters and .apply() function data class Mail(val to: String, var title: String = "", var message: String = "", var cc: List<String> = listOf(), var bcc: List<String> = listOf(), val attachments: List<java.io.File> = listOf()) { fun message(m: String) = apply { message = m } // No need to "return this" } val mail = Mail("bill.gates@microsoft.com") .message("How are you?").apply { cc = listOf("s.ballmer@microsoft.com") bcc = listOf("pichais@gmail.com") } Less boilerplate, same readability
  • 7. Proxy “Provides a substitute or placeholder for another object” Decorator and Proxy have different purposes but similar structures. Both describe how to provide a level of indirection to another object, and the implementations keep a reference to the object to which they forward requests. In Kotlin: by keyword is used for such delegation val image: File by lazy { println("Fetching image over network") val f = File.createTempFile("cat", ".jpg") URL(url).openStream().use { it.copyTo(BufferedOutputStream(f.outputStream())) }.also { println("Done fetching") } f }
  • 8. Iterator “Abstracts traversal of data structures in a linear way” class MyDataStructure<T> implements Iterable<T> { ... } In Java, this is built-in as Iterable interface Same will work also in Kotlin class MyDataStructure<T>: Iterable<T> { ... }
  • 9. Iterator - continued But in order not to have to implement too many interfaces (Android API, anyone?), you can use iterator() function instead: class MyDataStructure<T> { operator fun iterator() = object: Iterator<T> { override fun hasNext(): Boolean { ... } override fun next(): T { ... } } }
  • 10. State “Allows an object to alter its behavior when its internal state changes” sealed class Mood object Still : Mood() // class Aggressive(val madnessLevel: Int) : Mood() object Retreating : Mood() object Dead : Mood() Kotlin sealed classes are great for state management Since all descendants of a sealed class must reside in the same file, you also avoid lots of small files describing states in your project
  • 11. State - continued Best feature is that compiler makes sure that you check all states when using sealed class override fun seeHero() { mood = when(mood) { is Still -> Aggressive(2) is Aggressive -> Retreating is Retreating -> Aggressive(1) // Doesn't compile, when must be exhaustive } } override fun seeHero() { mood = when(mood) { is Still -> Aggressive(2) is Aggressive -> Retreating is Retreating -> Aggressive(1) is Dead -> Dead // Better } } You must either specify all conditions, or use else block
  • 12. Strategy “Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from the clients that use it.” class OurHero { private var direction = Direction.LEFT private var x: Int = 42 private var y: Int = 173 // Strategy var currentWeapon = Weapons.peashooter val shoot = fun() { currentWeapon(x, y, direction) } } In Kotlin functions are first class citizens. If you want to replace a method - replace a method, don’t talk.
  • 13. Strategy - continued object Weapons { val peashooter = fun(x: Int, y: Int, direction: Direction) { // Fly straight } val banana = fun(x: Int, y: Int, direction: Direction) { // Return when you hit screen border } val pomegranate = fun(x: Int, y: Int, direction: Direction) { // Explode when you hit first enemy } } You can encapsulate all available strategies And replace them at will val h = OurHero() h.shoot() // peashooter h.currentWeapon = Weapons.banana h.shoot() // banana
  • 14. Deferred value Not once I’ve heard JavaScript developers state that they don’t need design patterns in JavaScript. But Deferred value is one of the concurrent design patterns, and it’s widely used nowadays Also called Future or Promise with(GlobalScope) { val userProfile: Deferred<String> = async { delay(Random().nextInt(100).toLong()) "Profile" } } val profile: String = userProfile.await() In Kotlin provided as part of coroutines library:
  • 15. Fan Out “Deliver message to multiple destinations without halting the process” Producer Consumer 1 Consumer 2 Consumer 3 “r” “n” “d” Used to distribute work Each message delivered to only consumer, semi-randomly Kotlin coroutine library provides ReceiveChannel for that purpose fun CoroutineScope.producer(): ReceiveChannel<String> = produce { for (i in 1..1_000_000) { for (c in 'a' .. 'z') { send(c.toString()) // produce next } } }
  • 16. Fan Out - continued “Deliver message to multiple destinations without halting the process” Consumers can iterate over the channel, until it’s closed fun CoroutineScope.consumer(id: Int, channel: ReceiveChannel<String>) = launch { for (msg in channel) { println("Processor #$id received $msg") } } Here we distribute work between 4 consumers: val producer = producer() val processors = List(4) { consumer(it, producer) } for (p in processors) { p.join() }
  • 17. Fan In Similar to Fan Out pattern, Fan In relies on coroutines library and channels “Receive messages from multiple sources concurrently” fun CoroutineScope.collector(): SendChannel<Int> = actor { for (msg in channel) { println("Got $msg") } } Multiple producers are able to send to the same channel fun CoroutineScope.producer(id: Int, channel: SendChannel<Int>) = launch { repeat(10_000) { channel.send(id) } }
  • 18. Fan In - continued val collector = collector() val producers = List(4) { producer(it, collector) } producers.forEach { it.join() } Multiple producers are able to send to the same channel Outputs: ... Got 0 Got 0 Got 1 Got 2 Got 3 Got 0 Got 0 ...
  • 19. Summary ● Design patterns are everywhere ● Like any new language (unless it’s Go), Kotlin learns from shortcomings of its predecessors ● Kotlin has a lot of design patterns built in, as either idioms, language constructs or extension libraries ● Design patterns are not limited by GoF book
  • 21. Question time Thanks a lot for attending!

Editor's Notes

  • #4: © https://sourcemaking.com/design_patterns/singleton
  • #5: © https://sourcemaking.com/design_patterns/singleton
  • #6: © https://refactoring.guru/design-patterns/builder
  • #7: © https://refactoring.guru/design-patterns/builder
  • #8: © https://sourcemaking.com/design_patterns/proxy
  • #16: © https://en.wikipedia.org/wiki/Fan-out_(software) © https://kotlinlang.org/docs/reference/coroutines/channels.html#fan-out
  • #17: © https://en.wikipedia.org/wiki/Fan-out_(software) © https://kotlinlang.org/docs/reference/coroutines/channels.html#fan-out