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

Design Patterns in Kotlin

Sohel Shaikh
July 06, 2024
37

Design Patterns in Kotlin

Presented at KSUG, Surat

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