[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-7237":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":20,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":28,"readmeContent":29,"aiSummary":30,"trendingCount":16,"starSnapshotCount":16,"syncStatus":15,"lastSyncTime":31,"discoverSource":32},7237,"Design-Patterns-In-Kotlin","dbacinski\u002FDesign-Patterns-In-Kotlin","dbacinski","Design Patterns implemented in Kotlin","",null,"Kotlin",5998,688,194,2,0,4,39.51,"GNU General Public License v3.0",false,"master",true,[24,25,26,27],"design","design-patterns","kotlin","kotlin-android","2026-06-12 02:01:36","# Design Patterns In Kotlin\n\n#### :warning: New article about testing: [Unit Testing with Mockito 2](https:\u002F\u002Fgithub.com\u002Fdbacinski\u002FAndroid-Testing-With-Kotlin\u002Fblob\u002Fmaster\u002Fdocs\u002FUnit-Testing-Mockito.md)\n\nProject maintained by [@dbacinski](http:\u002F\u002Ftwitter.com\u002Fdbacinski) (Dariusz Baciński)\n\nInspired by [Design-Patterns-In-Swift](https:\u002F\u002Fgithub.com\u002Fochococo\u002FDesign-Patterns-In-Swift) by [@nsmeme](http:\u002F\u002Ftwitter.com\u002Fnsmeme) (Oktawian Chojnacki)\n\n## Table of Contents\n\n* [Behavioral Patterns](#behavioral)\n\t* [Observer \u002F Listener](#observer--listener)\n\t* [Strategy](#strategy)\n\t* [Command](#command)\n\t* [State](#state)\n\t* [Chain of Responsibility](#chain-of-responsibility)\n\t* [Visitor](#visitor)\n\t* [Mediator](#mediator)\n\t* [Memento](#memento)\n* [Creational Patterns](#creational)\n\t* [Builder \u002F Assembler](#builder--assembler)\n\t* [Factory Method](#factory-method)\n\t* [Singleton](#singleton)\n\t* [Abstract Factory](#abstract-factory)\n* [Structural Patterns](#structural)\n\t* [Adapter](#adapter)\n\t* [Decorator](#decorator)\n\t* [Facade](#facade)\n\t* [Protection Proxy](#protection-proxy)\n\t* [Composite](#composite)\n\nBehavioral\n==========\n\n>In software engineering, behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication.\n>\n>**Source:** [wikipedia.org](http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBehavioral_pattern)\n\n[Observer \u002F Listener](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FListener.kt)\n--------\n\nThe observer pattern is used to allow an object to publish changes to its state.\nOther objects subscribe to be immediately notified of any changes.\n\n#### Example\n\n```kotlin\ninterface TextChangedListener {\n\n    fun onTextChanged(oldText: String, newText: String)\n}\n\nclass PrintingTextChangedListener : TextChangedListener {\n    \n    private var text = \"\"\n    \n    override fun onTextChanged(oldText: String, newText: String) {\n        text = \"Text is changed: $oldText -> $newText\"\n    }\n}\n\nclass TextView {\n\n    val listeners = mutableListOf\u003CTextChangedListener>()\n\n    var text: String by Delegates.observable(\"\u003Cempty>\") { _, old, new ->\n        listeners.forEach { it.onTextChanged(old, new) }\n    }\n}\n```\n\n#### Usage\n\n```kotlin\nval textView = TextView().apply {\n    listeners.add(PrintingTextChangedListener())\n}\n\nwith(textView) {\n    text = \"Lorem ipsum\"\n    text = \"dolor sit amet\"\n}\n```\n\n#### Output\n\n```\nText is changed \u003Cempty> -> Lorem ipsum\nText is changed Lorem ipsum -> dolor sit amet\n```\n\n[Strategy](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FStrategy.kt)\n-----------\n\nThe strategy pattern is used to create an interchangeable family of algorithms from which the required process is chosen at run-time.\n\n#### Example\n\n```kotlin\nclass Printer(private val stringFormatterStrategy: (String) -> String) {\n\n    fun printString(string: String) {\n        println(stringFormatterStrategy(string))\n    }\n}\n\nval lowerCaseFormatter: (String) -> String = { it.toLowerCase() }\nval upperCaseFormatter = { it: String -> it.toUpperCase() }\n```\n\n#### Usage\n\n```kotlin\nval inputString = \"LOREM ipsum DOLOR sit amet\"\n\nval lowerCasePrinter = Printer(lowerCaseFormatter)\nlowerCasePrinter.printString(inputString)\n\nval upperCasePrinter = Printer(upperCaseFormatter)\nupperCasePrinter.printString(inputString)\n\nval prefixPrinter = Printer { \"Prefix: $it\" }\nprefixPrinter.printString(inputString)\n```\n\n#### Output\n\n```\nlorem ipsum dolor sit amet\nLOREM IPSUM DOLOR SIT AMET\nPrefix: LOREM ipsum DOLOR sit amet\n```\n\n[Command](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FCommand.kt)\n-------\n\nThe command pattern is used to express a request, including the call to be made and all of its required parameters, in a command object. The command may then be executed immediately or held for later use.\n\n#### Example:\n\n```kotlin\ninterface OrderCommand {\n    fun execute()\n}\n\nclass OrderAddCommand(val id: Long) : OrderCommand {\n    override fun execute() = println(\"Adding order with id: $id\")\n}\n\nclass OrderPayCommand(val id: Long) : OrderCommand {\n    override fun execute() = println(\"Paying for order with id: $id\")\n}\n\nclass CommandProcessor {\n\n    private val queue = ArrayList\u003COrderCommand>()\n\n    fun addToQueue(orderCommand: OrderCommand): CommandProcessor =\n        apply {\n            queue.add(orderCommand)\n        }\n\n    fun processCommands(): CommandProcessor =\n        apply {\n            queue.forEach { it.execute() }\n            queue.clear()\n        }\n}\n```\n\n#### Usage\n\n```kotlin\nCommandProcessor()\n    .addToQueue(OrderAddCommand(1L))\n    .addToQueue(OrderAddCommand(2L))\n    .addToQueue(OrderPayCommand(2L))\n    .addToQueue(OrderPayCommand(1L))\n    .processCommands()\n```\n\n#### Output\n\n```\nAdding order with id: 1\nAdding order with id: 2\nPaying for order with id: 2\nPaying for order with id: 1\n```\n\n[State](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FState.kt)\n------\n\nThe state pattern is used to alter the behaviour of an object as its internal state changes.\nThe pattern allows the class for an object to apparently change at run-time.\n\n#### Example\n\n```kotlin\nsealed class AuthorizationState\n\nobject Unauthorized : AuthorizationState()\n\nclass Authorized(val userName: String) : AuthorizationState()\n\nclass AuthorizationPresenter {\n\n    private var state: AuthorizationState = Unauthorized\n\n    val isAuthorized: Boolean\n        get() = when (state) {\n            is Authorized -> true\n            is Unauthorized -> false\n        }\n\n    val userName: String\n        get() {\n            val state = this.state \u002F\u002Fval enables smart casting of state\n            return when (state) {\n                is Authorized -> state.userName\n                is Unauthorized -> \"Unknown\"\n            }\n        }\n\n    fun loginUser(userName: String) {\n        state = Authorized(userName)\n    }\n\n    fun logoutUser() {\n        state = Unauthorized\n    }\n\n    override fun toString() = \"User '$userName' is logged in: $isAuthorized\"\n}\n```\n\n#### Usage\n\n```kotlin\nval authorizationPresenter = AuthorizationPresenter()\n\nauthorizationPresenter.loginUser(\"admin\")\nprintln(authorizationPresenter)\n\nauthorizationPresenter.logoutUser()\nprintln(authorizationPresenter)\n```\n\n#### Output\n\n```\nUser 'admin' is logged in: true\nUser 'Unknown' is logged in: false\n```\n\n[Chain of Responsibility](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FChainOfResponsibility.kt)\n-----------------------\n\nThe chain of responsibility pattern is used to process varied requests, each of which may be dealt with by a different handler.\n\n#### Example\n\n```kotlin\ninterface HeadersChain {\n    fun addHeader(inputHeader: String): String\n}\n\nclass AuthenticationHeader(val token: String?, var next: HeadersChain? = null) : HeadersChain {\n\n    override fun addHeader(inputHeader: String): String {\n        token ?: throw IllegalStateException(\"Token should be not null\")\n        return inputHeader + \"Authorization: Bearer $token\\n\"\n            .let { next?.addHeader(it) ?: it }\n    }\n}\n\nclass ContentTypeHeader(val contentType: String, var next: HeadersChain? = null) : HeadersChain {\n\n    override fun addHeader(inputHeader: String): String =\n        inputHeader + \"ContentType: $contentType\\n\"\n            .let { next?.addHeader(it) ?: it }\n}\n\nclass BodyPayload(val body: String, var next: HeadersChain? = null) : HeadersChain {\n\n    override fun addHeader(inputHeader: String): String =\n        inputHeader + body.let { next?.addHeader(it) ?: it }\n}\n```\n\n#### Usage\n\n```kotlin\n\u002F\u002Fcreate chain elements\nval authenticationHeader = AuthenticationHeader(\"123456\")\nval contentTypeHeader = ContentTypeHeader(\"json\")\nval messageBody = BodyPayload(\"Body:\\n{\\n\\\"username\\\"=\\\"dbacinski\\\"\\n}\")\n\n\u002F\u002Fconstruct chain\nauthenticationHeader.next = contentTypeHeader\ncontentTypeHeader.next = messageBody\n\n\u002F\u002Fexecute chain\nval messageWithAuthentication =\n    authenticationHeader.addHeader(\"Headers with Authentication:\\n\")\nprintln(messageWithAuthentication)\n\nval messageWithoutAuth =\n    contentTypeHeader.addHeader(\"Headers:\\n\")\nprintln(messageWithoutAuth)\n```\n\n#### Output\n\n```\nHeaders with Authentication:\nAuthorization: Bearer 123456\nContentType: json\nBody:\n{\n\"username\"=\"dbacinski\"\n}\n\nHeaders:\nContentType: json\nBody:\n{\n\"username\"=\"dbacinski\"\n}\n```\n\n[Visitor](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FVisitor.kt)\n-------\n\nThe visitor pattern is used to separate a relatively complex set of structured data classes from the functionality that may be performed upon the data that they hold.\n\n#### Example\n\n```kotlin\ninterface ReportVisitable {\n    fun \u003CR> accept(visitor: ReportVisitor\u003CR>): R\n}\n\nclass FixedPriceContract(val costPerYear: Long) : ReportVisitable {\n    override fun \u003CR> accept(visitor: ReportVisitor\u003CR>): R = visitor.visit(this)\n}\n\nclass TimeAndMaterialsContract(val costPerHour: Long, val hours: Long) : ReportVisitable {\n    override fun \u003CR> accept(visitor: ReportVisitor\u003CR>): R = visitor.visit(this)\n}\n\nclass SupportContract(val costPerMonth: Long) : ReportVisitable {\n    override fun \u003CR> accept(visitor: ReportVisitor\u003CR>): R = visitor.visit(this)\n}\n\ninterface ReportVisitor\u003Cout R> {\n\n    fun visit(contract: FixedPriceContract): R\n    fun visit(contract: TimeAndMaterialsContract): R\n    fun visit(contract: SupportContract): R\n}\n\nclass MonthlyCostReportVisitor : ReportVisitor\u003CLong> {\n\n    override fun visit(contract: FixedPriceContract): Long =\n        contract.costPerYear \u002F 12\n\n    override fun visit(contract: TimeAndMaterialsContract): Long =\n        contract.costPerHour * contract.hours\n\n    override fun visit(contract: SupportContract): Long =\n        contract.costPerMonth\n}\n\nclass YearlyReportVisitor : ReportVisitor\u003CLong> {\n\n    override fun visit(contract: FixedPriceContract): Long =\n        contract.costPerYear\n\n    override fun visit(contract: TimeAndMaterialsContract): Long =\n        contract.costPerHour * contract.hours\n\n    override fun visit(contract: SupportContract): Long =\n        contract.costPerMonth * 12\n}\n```\n\n#### Usage\n\n```kotlin\nval projectAlpha = FixedPriceContract(costPerYear = 10000)\nval projectGamma = TimeAndMaterialsContract(hours = 150, costPerHour = 10)\nval projectBeta = SupportContract(costPerMonth = 500)\nval projectKappa = TimeAndMaterialsContract(hours = 50, costPerHour = 50)\n\nval projects = arrayOf(projectAlpha, projectBeta, projectGamma, projectKappa)\n\nval monthlyCostReportVisitor = MonthlyCostReportVisitor()\n\nval monthlyCost = projects.map { it.accept(monthlyCostReportVisitor) }.sum()\nprintln(\"Monthly cost: $monthlyCost\")\nassertThat(monthlyCost).isEqualTo(5333)\n\nval yearlyReportVisitor = YearlyReportVisitor()\nval yearlyCost = projects.map { it.accept(yearlyReportVisitor) }.sum()\nprintln(\"Yearly cost: $yearlyCost\")\nassertThat(yearlyCost).isEqualTo(20000)\n```\n\n#### Output\n\n```\nMonthly cost: 5333\nYearly cost: 20000\n```\n\n[Mediator](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FMediator.kt)\n-------\n\nMediator design pattern is used to provide a centralized communication medium between different objects in a system. This pattern is very helpful in an enterprise application where multiple objects are interacting with each other.\n#### Example\n\n```kotlin\nclass ChatUser(private val mediator: ChatMediator, val name: String) {\n    fun send(msg: String) {\n        println(\"$name: Sending Message= $msg\")\n        mediator.sendMessage(msg, this)\n    }\n\n    fun receive(msg: String) {\n        println(\"$name: Message received: $msg\")\n    }\n}\n\nclass ChatMediator {\n\n    private val users: MutableList\u003CChatUser> = ArrayList()\n\n    fun sendMessage(msg: String, user: ChatUser) {\n        users\n            .filter { it != user }\n            .forEach {\n                it.receive(msg)\n            }\n    }\n\n    fun addUser(user: ChatUser): ChatMediator =\n        apply { users.add(user) }\n\n}\n```\n\n#### Usage\n\n```kotlin\nval mediator = ChatMediator()\nval john = ChatUser(mediator, \"John\")\n\nmediator\n    .addUser(ChatUser(mediator, \"Alice\"))\n    .addUser(ChatUser(mediator, \"Bob\"))\n    .addUser(john)\njohn.send(\"Hi everyone!\")\n```\n\n#### Output\n\n```\nJohn: Sending Message= Hi everyone!\nAlice: Message received: Hi everyone!\nBob: Message received: Hi everyone!\n```\n\n[Memento](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FMemento.kt)\n-------\n\nThe memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback).\n\n#### Example\n```kotlin\ndata class Memento(val state: String)\n\nclass Originator(var state: String) {\n\n    fun createMemento(): Memento {\n        return Memento(state)\n    }\n\n    fun restore(memento: Memento) {\n        state = memento.state\n    }\n}\n\nclass CareTaker {\n    private val mementoList = ArrayList\u003CMemento>()\n\n    fun saveState(state: Memento) {\n        mementoList.add(state)\n    }\n\n    fun restore(index: Int): Memento {\n        return mementoList[index]\n    }\n}\n```\n\n#### Usage\n```kotlin\nval originator = Originator(\"initial state\")\nval careTaker = CareTaker()\ncareTaker.saveState(originator.createMemento())\n\noriginator.state = \"State #1\"\noriginator.state = \"State #2\"\ncareTaker.saveState(originator.createMemento())\n\noriginator.state = \"State #3\"\nprintln(\"Current State: \" + originator.state)\nassertThat(originator.state).isEqualTo(\"State #3\")\n\noriginator.restore(careTaker.restore(1))\nprintln(\"Second saved state: \" + originator.state)\nassertThat(originator.state).isEqualTo(\"State #2\")\n\noriginator.restore(careTaker.restore(0))\nprintln(\"First saved state: \" + originator.state)\n```\n\n#### Output\n```\nCurrent State: State #3\nSecond saved state: State #2\nFirst saved state: initial state\n```\n\nCreational\n==========\n\n> In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation.\n>\n>**Source:** [wikipedia.org](http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCreational_pattern)\n\n[Builder \u002F Assembler](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FBuilder.kt)\n----------\n\nThe builder pattern is used to create complex objects with constituent parts that must be created in the same order or using a specific algorithm.\nAn external class controls the construction algorithm.\n\n#### Example\n\n```kotlin\n\u002F\u002F Let's assume that Dialog class is provided by external library.\n\u002F\u002F We have only access to Dialog public interface which cannot be changed.\n\nclass Dialog {\n\n    fun showTitle() = println(\"showing title\")\n\n    fun setTitle(text: String) = println(\"setting title text $text\")\n\n    fun setTitleColor(color: String) = println(\"setting title color $color\")\n\n    fun showMessage() = println(\"showing message\")\n\n    fun setMessage(text: String) = println(\"setting message $text\")\n\n    fun setMessageColor(color: String) = println(\"setting message color $color\")\n\n    fun showImage(bitmapBytes: ByteArray) = println(\"showing image with size ${bitmapBytes.size}\")\n\n    fun show() = println(\"showing dialog $this\")\n}\n\n\u002F\u002FBuilder:\nclass DialogBuilder() {\n    constructor(init: DialogBuilder.() -> Unit) : this() {\n        init()\n    }\n\n    private var titleHolder: TextView? = null\n    private var messageHolder: TextView? = null\n    private var imageHolder: File? = null\n\n    fun title(init: TextView.() -> Unit) {\n        titleHolder = TextView().apply { init() }\n    }\n\n    fun message(init: TextView.() -> Unit) {\n        messageHolder = TextView().apply { init() }\n    }\n\n    fun image(init: () -> File) {\n        imageHolder = init()\n    }\n\n    fun build(): Dialog {\n        val dialog = Dialog()\n\n        titleHolder?.apply {\n            dialog.setTitle(text)\n            dialog.setTitleColor(color)\n            dialog.showTitle()\n        }\n\n        messageHolder?.apply {\n            dialog.setMessage(text)\n            dialog.setMessageColor(color)\n            dialog.showMessage()\n        }\n\n        imageHolder?.apply {\n            dialog.showImage(readBytes())\n        }\n\n        return dialog\n    }\n\n    class TextView {\n        var text: String = \"\"\n        var color: String = \"#00000\"\n    }\n}\n```\n\n#### Usage\n\n```kotlin\n\u002F\u002FFunction that creates dialog builder and builds Dialog\nfun dialog(init: DialogBuilder.() -> Unit): Dialog {\n    return DialogBuilder(init).build()\n}\n\nval dialog: Dialog = dialog {\n    title {\n        text = \"Dialog Title\"\n    }\n    message {\n        text = \"Dialog Message\"\n        color = \"#333333\"\n    }\n    image {\n        File.createTempFile(\"image\", \"jpg\")\n    }\n}\n\ndialog.show()\n```\n\n#### Output\n\n```\nsetting title text Dialog Title\nsetting title color #00000\nshowing title\nsetting message Dialog Message\nsetting message color #333333\nshowing message\nshowing image with size 0\nshowing dialog Dialog@5f184fc6\n```\n\n[Factory Method](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FFactoryMethod.kt)\n-----------------\n\nThe factory pattern is used to replace class constructors, abstracting the process of object generation so that the type of the object instantiated can be determined at run-time.\n\n#### Example\n\n```kotlin\nsealed class Country {\n    object USA : Country() \u002F\u002FKotlin 1.0 could only be an inner class or object\n}\n\nobject Spain : Country() \u002F\u002FKotlin 1.1 declared as top level class\u002Fobject in the same file\nclass Greece(val someProperty: String) : Country()\ndata class Canada(val someProperty: String) : Country() \u002F\u002FKotlin 1.1 data class extends other class\n\u002F\u002Fobject Poland : Country()\n\nclass Currency(\n    val code: String\n)\n\nobject CurrencyFactory {\n\n    fun currencyForCountry(country: Country): Currency =\n        when (country) {\n            is Greece -> Currency(\"EUR\")\n            is Spain -> Currency(\"EUR\")\n            is Country.USA -> Currency(\"USD\")\n            is Canada -> Currency(\"CAD\")\n        }  \u002F\u002Ftry to add a new country Poland, it won't even compile without adding new branch to 'when'\n}\n```\n\n#### Usage\n\n```kotlin\nval greeceCurrency = CurrencyFactory.currencyForCountry(Greece(\"\")).code\nprintln(\"Greece currency: $greeceCurrency\")\n\nval usaCurrency = CurrencyFactory.currencyForCountry(Country.USA).code\nprintln(\"USA currency: $usaCurrency\")\n\nassertThat(greeceCurrency).isEqualTo(\"EUR\")\nassertThat(usaCurrency).isEqualTo(\"USD\")\n```\n\n#### Output\n\n```\nGreece currency: EUR\nUS currency: USD\nUK currency: No Currency Code Available\n```\n\n[Singleton](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FSingleton.kt)\n------------\n\nThe singleton pattern ensures that only one object of a particular class is ever created.\nAll further references to objects of the singleton class refer to the same underlying instance.\nThere are very few applications, do not overuse this pattern!\n\n#### Example:\n\n```kotlin\nobject PrinterDriver {\n    init {\n        println(\"Initializing with object: $this\")\n    }\n\n    fun print() = println(\"Printing with object: $this\")\n}\n```\n\n#### Usage\n\n```kotlin\nprintln(\"Start\")\nPrinterDriver.print()\nPrinterDriver.print()\n```\n\n#### Output\n\n```\nStart\nInitializing with object: PrinterDriver@6ff3c5b5\nPrinting with object: PrinterDriver@6ff3c5b5\nPrinting with object: PrinterDriver@6ff3c5b5\n```\n\n[Abstract Factory](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FAbstractFactory.kt)\n-------------------\n\nThe abstract factory pattern is used to provide a client with a set of related or dependant objects.\nThe \"family\" of objects created by the factory are determined at run-time.\n\n#### Example\n\n```kotlin\ninterface Plant\n\nclass OrangePlant : Plant\n\nclass ApplePlant : Plant\n\nabstract class PlantFactory {\n    abstract fun makePlant(): Plant\n\n    companion object {\n        inline fun \u003Creified T : Plant> createFactory(): PlantFactory = when (T::class) {\n            OrangePlant::class -> OrangeFactory()\n            ApplePlant::class  -> AppleFactory()\n            else               -> throw IllegalArgumentException()\n        }\n    }\n}\n\nclass AppleFactory : PlantFactory() {\n    override fun makePlant(): Plant = ApplePlant()\n}\n\nclass OrangeFactory : PlantFactory() {\n    override fun makePlant(): Plant = OrangePlant()\n}\n```\n\n#### Usage\n\n```kotlin\nval plantFactory = PlantFactory.createFactory\u003COrangePlant>()\nval plant = plantFactory.makePlant()\nprintln(\"Created plant: $plant\")\n```\n\n#### Output\n\n```kotlin\nCreated plant: OrangePlant@4f023edb\n```\n\nStructural\n==========\n\n>In software engineering, structural design patterns are design patterns that ease the design by identifying a simple way to realize relationships between entities.\n>\n>**Source:** [wikipedia.org](http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FStructural_pattern)\n\n[Adapter](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FAdapter.kt)\n----------\n\nThe adapter pattern is used to provide a link between two otherwise incompatible types by wrapping the \"adaptee\" with a class that supports the interface required by the client.\n\n#### Example\n\n```kotlin\ninterface Temperature {\n    var temperature: Double\n}\n\nclass CelsiusTemperature(override var temperature: Double) : Temperature\n\nclass FahrenheitTemperature(var celsiusTemperature: CelsiusTemperature) : Temperature {\n\n    override var temperature: Double\n        get() = convertCelsiusToFahrenheit(celsiusTemperature.temperature)\n        set(temperatureInF) {\n            celsiusTemperature.temperature = convertFahrenheitToCelsius(temperatureInF)\n        }\n\n    private fun convertFahrenheitToCelsius(f: Double): Double = (f - 32) * 5 \u002F 9\n\n    private fun convertCelsiusToFahrenheit(c: Double): Double = (c * 9 \u002F 5) + 32\n}\n\n```\n\n#### Usage\n\n```kotlin\nval celsiusTemperature = CelsiusTemperature(0.0)\nval fahrenheitTemperature = FahrenheitTemperature(celsiusTemperature)\n\ncelsiusTemperature.temperature = 36.6\nprintln(\"${celsiusTemperature.temperature} C -> ${fahrenheitTemperature.temperature} F\")\n\nfahrenheitTemperature.temperature = 100.0\nprintln(\"${fahrenheitTemperature.temperature} F -> ${celsiusTemperature.temperature} C\")\n```\n\n#### Output\n\n```\n36.6 C -> 97.88000000000001 F\n100.0 F -> 37.77777777777778 C\n```\n\n[Decorator](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FDecorator.kt)\n------------\n\nThe decorator pattern is used to extend or alter the functionality of objects at run-time by wrapping them in an object of a decorator class.\nThis provides a flexible alternative to using inheritance to modify behaviour.\n\n#### Example\n\n```kotlin\ninterface CoffeeMachine {\n    fun makeSmallCoffee()\n    fun makeLargeCoffee()\n}\n\nclass NormalCoffeeMachine : CoffeeMachine {\n    override fun makeSmallCoffee() = println(\"Normal: Making small coffee\")\n\n    override fun makeLargeCoffee() = println(\"Normal: Making large coffee\")\n}\n\n\u002F\u002FDecorator:\nclass EnhancedCoffeeMachine(val coffeeMachine: CoffeeMachine) : CoffeeMachine by coffeeMachine {\n\n    \u002F\u002F overriding behaviour\n    override fun makeLargeCoffee() {\n        println(\"Enhanced: Making large coffee\")\n        coffeeMachine.makeLargeCoffee()\n    }\n\n    \u002F\u002F extended behaviour\n    fun makeCoffeeWithMilk() {\n        println(\"Enhanced: Making coffee with milk\")\n        coffeeMachine.makeSmallCoffee()\n        println(\"Enhanced: Adding milk\")\n    }\n}\n```\n\n#### Usage\n\n```kotlin\n    val normalMachine = NormalCoffeeMachine()\n    val enhancedMachine = EnhancedCoffeeMachine(normalMachine)\n\n    \u002F\u002F non-overridden behaviour\n    enhancedMachine.makeSmallCoffee()\n    \u002F\u002F overriding behaviour\n    enhancedMachine.makeLargeCoffee()\n    \u002F\u002F extended behaviour\n    enhancedMachine.makeCoffeeWithMilk()\n```\n\n#### Output\n\n```\nNormal: Making small coffee\n\nEnhanced: Making large coffee\nNormal: Making large coffee\n\nEnhanced: Making coffee with milk\nNormal: Making small coffee\nEnhanced: Adding milk\n```\n\n[Facade](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FFacade.kt)\n---------\n\nThe facade pattern is used to define a simplified interface to a more complex subsystem.\n\n#### Example\n\n```kotlin\nclass ComplexSystemStore(val filePath: String) {\n\n    init {\n        println(\"Reading data from file: $filePath\")\n    }\n\n    val store = HashMap\u003CString, String>()\n\n    fun store(key: String, payload: String) {\n        store.put(key, payload)\n    }\n\n    fun read(key: String): String = store[key] ?: \"\"\n\n    fun commit() = println(\"Storing cached data: $store to file: $filePath\")\n}\n\ndata class User(val login: String)\n\n\u002F\u002FFacade:\nclass UserRepository {\n    val systemPreferences = ComplexSystemStore(\"\u002Fdata\u002Fdefault.prefs\")\n\n    fun save(user: User) {\n        systemPreferences.store(\"USER_KEY\", user.login)\n        systemPreferences.commit()\n    }\n\n    fun findFirst(): User = User(systemPreferences.read(\"USER_KEY\"))\n}\n```\n\n#### Usage\n\n```kotlin\nval userRepository = UserRepository()\nval user = User(\"dbacinski\")\nuserRepository.save(user)\nval resultUser = userRepository.findFirst()\nprintln(\"Found stored user: $resultUser\")\n```\n\n#### Ouput\n\n```\nReading data from file: \u002Fdata\u002Fdefault.prefs\nStoring cached data: {USER_KEY=dbacinski} to file: \u002Fdata\u002Fdefault.prefs\nFound stored user: User(login=dbacinski)\n```\n\n[Protection Proxy](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FProtectionProxy.kt)\n------------------\n\nThe proxy pattern is used to provide a surrogate or placeholder object, which references an underlying object.\nProtection proxy is restricting access.\n\n#### Example\n\n```kotlin\ninterface File {\n    fun read(name: String)\n}\n\nclass NormalFile : File {\n    override fun read(name: String) = println(\"Reading file: $name\")\n}\n\n\u002F\u002FProxy:\nclass SecuredFile : File {\n    val normalFile = NormalFile()\n    var password: String = \"\"\n\n    override fun read(name: String) {\n        if (password == \"secret\") {\n            println(\"Password is correct: $password\")\n            normalFile.read(name)\n        } else {\n            println(\"Incorrect password. Access denied!\")\n        }\n    }\n}\n```\n\n#### Usage\n\n```kotlin\nval securedFile = SecuredFile()\nsecuredFile.read(\"readme.md\")\n\nsecuredFile.password = \"secret\"\nsecuredFile.read(\"readme.md\")\n```\n\n#### Ouput\n\n```\nIncorrect password. Access denied!\nPassword is correct: secret\nReading file: readme.md\n```\n\n\n\n[Composite](\u002Fpatterns\u002Fsrc\u002Ftest\u002Fkotlin\u002FComposite.kt)\n------------------\n\nThe composite pattern is used to compose zero-or-more similar \nobjects so that they can be manipulated as one object.\n\n#### Example\n\n```kotlin\n\nopen class Equipment(private var price: Int, private var name: String) {\n    open fun getPrice(): Int = price\n}\n\n\n\u002F*\n[composite]\n*\u002F\n\nopen class Composite(name: String) : Equipment(0, name) {\n    val equipments = ArrayList\u003CEquipment>()\n\n    fun add(equipment: Equipment) {\n        this.equipments.add(equipment)\n    }\n\n    override fun getPrice(): Int {\n        return equipments.map { it.getPrice() }.sum()\n    }\n}\n\n\n\u002F*\n leafs\n*\u002F\n\nclass Cabbinet : Composite(\"cabbinet\")\nclass FloppyDisk : Equipment(70, \"Floppy Disk\")\nclass HardDrive : Equipment(250, \"Hard Drive\")\nclass Memory : Equipment(280, \"Memory\")\n\n\n```\n\n#### Usage\n\n```kotlin\nvar cabbinet = Cabbinet()\ncabbinet.add(FloppyDisk())\ncabbinet.add(HardDrive())\ncabbinet.add(Memory())\nprintln(cabbinet.getPrice())\n```\n\n#### Ouput\n\n```\n600\n```\n\n\n\nInfo\n====\n\nDescriptions from: [Gang of Four Design Patterns Reference Sheet](http:\u002F\u002Fwww.blackwasp.co.uk\u002FGangOfFour.aspx)\n","该项目是一个用 Kotlin 语言实现的设计模式集合。它涵盖了行为型、创建型和结构型三大类设计模式，包括观察者、策略、工厂方法等常见模式的具体实现。项目不仅为开发者提供了丰富的设计模式示例代码，还通过详细的注释帮助理解每种模式的应用场景与工作原理，非常适合想要深入学习面向对象设计原则及Kotlin编程的开发者。此外，对于正在使用Kotlin进行Android开发或希望提高代码可维护性和灵活性的团队来说，这个项目也是一个宝贵的资源。","2026-06-11 03:11:19","top_language"]