Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Design Patterns in Kotlin

Avatar for Sohel Shaikh Sohel Shaikh
July 06, 2024
44

Design Patterns in Kotlin

Presented at KSUG, Surat

Avatar for Sohel Shaikh

Sohel Shaikh

July 06, 2024
Tweet

Transcript

  1. - 4+ YOE with Android - Lead Android Engineer @

    Skylark Drones - I 💜 Kotlin! - @thesohelshaikh on Socials Hey, I am Sohel
  2. A Pattern is a solution to a problem in a

    context. A recurring situation
  3. A Pattern is a solution to a problem in a

    context. A recurring situation Goal in context
  4. A Pattern is a solution to a problem in a

    context. A recurring situation Goal in context The design
  5. Why bother? - Shared vocabularies - Discussions at a higher

    level - Tried and tested solutions - Easy to reuse
  6. Singleton with Params class AppDatabase { companion object { private

    var INSTANCE: YTDatabase? = null fun getDatabase(context: Context): AppDatabase { return INSTANCE -: Room.databaseBuilder( context.applicationContext, AppDatabase-:class.java, "app_database" ).build().apply { INSTANCE = this } } } }
  7. Singleton with Params class AppDatabase { companion object { private

    var INSTANCE: YTDatabase? = null fun getDatabase(context: Context): AppDatabase { return INSTANCE -: Room.databaseBuilder( context.applicationContext, AppDatabase-:class.java, "app_database" ).build().apply { INSTANCE = this } } } }
  8. Singleton with Params class AppDatabase { companion object { private

    var INSTANCE: YTDatabase? = null fun getDatabase(context: Context): AppDatabase { return INSTANCE -: Room.databaseBuilder( context.applicationContext, AppDatabase-:class.java, "app_database" ).build().apply { INSTANCE = this } } } }
  9. Singleton with Params (Thread safe) class AppDatabase { companion object

    { @Volatile private var INSTANCE: YTDatabase? = null fun getDatabase(context: Context): AppDatabase { return INSTANCE -: synchronized(this) { val instance = Room.databaseBuilder( context.applicationContext, AppDatabase-:class.java, "app_database" ).build().apply { INSTANCE = instance } } } } }
  10. Singleton with Params (Thread safe) class AppDatabase { companion object

    { @Volatile private var INSTANCE: YTDatabase? = null fun getDatabase(context: Context): AppDatabase { return INSTANCE -: synchronized(this) { val instance = Room.databaseBuilder( context.applicationContext, AppDatabase-:class.java, "app_database" ).build().apply { INSTANCE = instance } } } } }
  11. Singleton with Params (Thread safe) class MyApplication : Application() {

    val database by lazy { AppDatabase.getDatabase(this) } }
  12. Singleton Cons - Creates Global state - Hard to debug

    - Hard to test - Hides a complex design flaw - Thread safety handling
  13. class KotlinNewsLetter { val newestArticleObservers = mutableListOf<KotlinDeveloper>() var newestArticleUrl: String

    by Delegates.observable("") { _, _, newValue -> newestArticleObservers.forEach { it.read(newValue) } } } Kotlin Delegates
  14. class KotlinNewsLetter { val newestArticleObservers = mutableListOf<KotlinDeveloper>() var newestArticleUrl: String

    by Delegates.observable("") { _, _, newValue -> newestArticleObservers.forEach { it.read(newValue) } } } Kotlin Delegates
  15. class KotlinNewsLetter { val newestArticleObservers = mutableListOf<KotlinDeveloper>() var newestArticleUrl: String

    by Delegates.observable("") { _, _, newValue -> newestArticleObservers.forEach { it.read(newValue) } } } class KotlinDeveloper { fun read(article: String) { println("$this Reading $article") } } Kotlin Delegates
  16. val newsLetter = KotlinNewsLetter() val developerAlpha = KotlinDeveloper() val developerBeta

    = KotlinDeveloper() newsLetter.newestArticleObservers.add(developerAlpha) newsLetter.newestArticleObservers.add(developerBeta) newsLetter.newestArticleUrl = "www.kotlin.com" newsLetter.newestArticleUrl = "www.java-is-bad.com"
  17. Factory Pattern enum class ExportFormat{ Csv, Pdf } interface Exporter

    { fun export(): File } class CsvExporter: Exporter { override fun export(): File { --. } } class PdfExporter: Exporter { override fun export(): File { --. } }
  18. Factory Pattern class ExporterFactory { companion object { fun create(format:

    ExportFormat): Exporter { return when(format) { ExportFormat.Csv -> CsvExporter() ExportFormat.Pdf -> PdfExporter() } } } }
  19. Memento Pattern Use the Memento Pattern when you need to

    be able to return an object to one of its previous states; for instance, if your user requests an “undo.”
  20. Design Principle Identify the aspects of your application that vary

    and separate them from what stays the same.
  21. Be Cautious! - Another tool in the toolbox - Hard

    to refactor later - Focus on the problem