idiomatic-kotlin-course/notebooks/Kotlin design patterns.ipynb

1552 lines
32 KiB
Plaintext
Raw Normal View History

2024-10-29 09:30:55 +03:00
{
"cells":[
{
"cell_type":"markdown",
"source":[
"# Sheet"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"Sheet",
"type":"MD",
"hide_input_from_viewers":false,
"hide_output_from_viewers":false,
"sheet_delimiter":true
}
}
},
{
"cell_type":"markdown",
"source":[
"# Factories"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"kfka3l54zO2cbMlMjZser7",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"interface A{\n",
" val body: String\n",
"}\n",
"\n",
"class B(override val body: String): A{\n",
" override fun toString() = \"$body B\"\n",
"}\n",
"\n",
"class C(override val body: String): A{\n",
" override fun toString() = \"$body C\"\n",
"}\n",
"\n",
"fun print(obj: A){\n",
" println(obj)\n",
"}"
],
"execution_count":9,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"w3yuNLSDBka2TYCaWojtxM",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"print(C(\"My body\"))"
],
"execution_count":10,
"outputs":[
{
"name":"stdout",
"text":[
"My body C\n"
],
"output_type":"stream"
}
],
"metadata":{
"datalore":{
"node_id":"uBjdJBVkelSda73M9M9KVt",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"interface AFactory<out T: A>{\n",
" fun create(body: String): T\n",
"}\n",
"\n",
"object BFactory: AFactory<B>{\n",
" override fun create(body: String): B = B(body)\n",
"}\n",
"\n",
"fun <T: A> createWithAWord(word: String, factory: AFactory<T>) = factory.create(\"Word: $word\")"
],
"execution_count":14,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"bOHAAqwHwERE2KjWbCpYnR",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"createWithAWord(\"Hello\", BFactory)"
],
"execution_count":15,
"outputs":[
{
"data":{
"text\/plain":[
"Word: Hello B"
]
},
"metadata":{},
"output_type":"display_data"
}
],
"metadata":{
"datalore":{
"node_id":"FQCZ6JUVsv30zSrNgFusW9",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"fun <T: A> createWithAWord(word: String, factoryFunction: (String) -> T) = factoryFunction(\"Word: $word\")"
],
"execution_count":17,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"A60omBLPluLVcheSHMCwbO",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"createWithAWord(\"Hello\", ::B)"
],
"execution_count":19,
"outputs":[
{
"data":{
"text\/plain":[
"Word: Hello B"
]
},
"metadata":{},
"output_type":"display_data"
}
],
"metadata":{
"datalore":{
"node_id":"NjSa4JlkOMYs1wcUFMkxqb",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"createWithAWord(\"Hello\"){body -> B(\">\\t$body\")}"
],
"execution_count":21,
"outputs":[
{
"data":{
"text\/plain":[
">\tWord: Hello B"
]
},
"metadata":{},
"output_type":"display_data"
}
],
"metadata":{
"datalore":{
"node_id":"TvX8qzziDGxZWf044iqHO3",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"# Factory functions"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"3iPAMgURNX1IdwhklIXETa",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"data class Client(val url: String)\n",
"\n",
"interface Request{\n",
" val client: Client\n",
"}\n",
"\n",
"data class RequestImpl(override val client: Client): Request{\n",
"\/\/ constructor(url: String): this(Client(url))\n",
"}"
],
"execution_count":2,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"yVwMw3CpejJHhnEQDCab6g",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"fun Request(url: String): Request{\n",
" return RequestImpl(Client(url))\n",
"}"
],
"execution_count":4,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"72D1rEcXVM7hutTX65ouiE",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"Request(\"DDD\")"
],
"execution_count":5,
"outputs":[
{
"data":{
"text\/plain":[
"RequestImpl(client=Client(url=DDD))"
]
},
"metadata":{},
"output_type":"display_data"
}
],
"metadata":{
"datalore":{
"node_id":"9Y1icG6BtLX5P0uF879Baq",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"listOf(1,2,3)"
],
"execution_count":33,
"outputs":[
{
"data":{
"text\/plain":[
"[1, 2, 3]"
]
},
"metadata":{},
"output_type":"display_data"
}
],
"metadata":{
"datalore":{
"node_id":"3yvFzSrCRK7m3o90gysDVm",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"# Lazy"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"IttR7MZNzaf78FGtuNcLEx",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"class WithLazy{\n",
" val prop = 2\n",
" get(){\n",
" println(\"Hit $field\")\n",
" return field\n",
" }\n",
"\n",
" val lazyProp by lazy{\n",
" println(\"Hit lazy\")\n",
" 2\n",
" }\n",
"}"
],
"execution_count":12,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"h0jgOzZDe8PiryzcHnNdBG",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"val withLazy = WithLazy()"
],
"execution_count":13,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"5lXgZjAPOpwswgQpZIC0NO",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"withLazy.prop\n",
"withLazy.prop\n",
"withLazy.prop"
],
"execution_count":14,
"outputs":[
{
"name":"stdout",
"text":[
"Hit 2\n",
"Hit 2\n",
"Hit 2\n"
],
"output_type":"stream"
},
{
"data":{
"text\/plain":[
"2"
]
},
"metadata":{},
"output_type":"display_data"
}
],
"metadata":{
"datalore":{
"node_id":"C6VAvJWSYieH6LGfrgNvQ5",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"withLazy.lazyProp\n",
"withLazy.lazyProp\n",
"withLazy.lazyProp"
],
"execution_count":15,
"outputs":[
{
"name":"stdout",
"text":[
"Hit lazy\n"
],
"output_type":"stream"
},
{
"data":{
"text\/plain":[
"2"
]
},
"metadata":{},
"output_type":"display_data"
}
],
"metadata":{
"datalore":{
"node_id":"rJLM2Kv6yvJQf9bNMpcsB9",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"# Builder"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"XYoUXQu8GD51C080v5thFD",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"data class Buildable(\n",
" var a: Int = 1,\n",
" var b: Int = 2,\n",
" var c: Int = 3\n",
"){\n",
" fun setABC(value: Int){\n",
" a = value\n",
" b = value\n",
" c = value\n",
" }\n",
"}\n",
"\n",
"\/\/ Buildable.builder()\n",
"\/\/ .setA(1)\n",
"\/\/ .setB(2)\n",
"\/\/ .setC(3)\n",
"\/\/ .setABC(1)\n",
"\/\/ .build()"
],
"execution_count":7,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"nlm610q2oEsKlSDE1pXtkG",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"Buildable(b = 5)"
],
"execution_count":8,
"outputs":[
{
"data":{
"text\/plain":[
"Buildable(a=1, b=5, c=3)"
]
},
"metadata":{},
"output_type":"display_data"
}
],
"metadata":{
"datalore":{
"node_id":"EQoUX3r984KJvt9tkpy3Wd",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"Buildable().apply { \n",
" a = 1\n",
" setABC(a + b + c)\n",
"}"
],
"execution_count":9,
"outputs":[
{
"data":{
"text\/plain":[
"Buildable(a=6, b=6, c=6)"
]
},
"metadata":{},
"output_type":"display_data"
}
],
"metadata":{
"datalore":{
"node_id":"hJnD2AzKDTgYkrZoyf31Hd",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"fun Buildable(block: Buildable.()-> Unit): Buildable = Buildable().apply(block)\n",
"\n",
"Buildable{ \n",
" a = 1\n",
" setABC(a + b + c)\n",
"}"
],
"execution_count":11,
"outputs":[
{
"data":{
"text\/plain":[
"Buildable(a=6, b=6, c=6)"
]
},
"metadata":{},
"output_type":"display_data"
}
],
"metadata":{
"datalore":{
"node_id":"eybgzzEc7H4Px2nL7CKvvt",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"# Multiton"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"g33v0kYJUYOULVwSfxeGhB",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"class Multiton private constructor(val name: String){\n",
" init{\n",
" println(\"Multiton $name created\")\n",
" }\n",
" \n",
" companion object {\n",
" private val cache = HashMap<String, Multiton>()\n",
"\n",
" fun resolve(name: String) = cache.getOrPut(name){Multiton(name)}\n",
" }\n",
"}"
],
"execution_count":16,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"jWHHMghzB2djqbkxMUA6Tx",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"Multiton.resolve(\"a\")\n",
"Multiton.resolve(\"a\")\n",
"Multiton.resolve(\"b\")\n",
"Multiton.resolve(\"a\")"
],
"execution_count":17,
"outputs":[
{
"name":"stdout",
"text":[
"Multiton a created\n",
"Multiton b created\n"
],
"output_type":"stream"
},
{
"data":{
"text\/plain":[
"Line_61_jupyter$Multiton@5271dd0f"
]
},
"metadata":{},
"output_type":"display_data"
}
],
"metadata":{
"datalore":{
"node_id":"lc75iGLEUf7H0uXMTaIXHx",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"Multiton(\"v\")"
],
"execution_count":18,
"outputs":[
{
"name":"stderr",
"text":[
"Line_67.jupyter.kts (1:1 - 9) Cannot access '<init>': it is private in 'Multiton'"
],
"output_type":"stream"
},
{
"ename":"Syntax Error",
"evalue":"Syntax Error: Cannot access '<init>': it is private in 'Multiton'",
"traceback":[
"\u001b[0;31m---------------------------------------------------------------------------",
"Traceback (most recent call last)",
"Syntax Error: Cannot access '<init>': it is private in 'Multiton'"
],
"output_type":"error"
}
],
"metadata":{
"datalore":{
"node_id":"q7uzHnibwUrfQT3IbMmcce",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"sealed interface SealedMultiton{\n",
" object A: SealedMultiton\n",
" object B: SealedMultiton\n",
" class Custom(val body: String): SealedMultiton\n",
"}\n",
"\n",
"fun evaluateSealedMultiton(sealed: SealedMultiton) = when(sealed){\n",
" is SealedMultiton.A-> println(\"A\")\n",
" is SealedMultiton.B-> println(\"B\")\n",
" is SealedMultiton.Custom -> println(sealed.body)\n",
"}"
],
"execution_count":24,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"6GgWOmtJcF5yzCoPf7PbRE",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"# Adapter"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"YfxaLKY0BwQjCnS48Fkh3z",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"val array = doubleArrayOf(1.0,2.0)\n",
"val list = listOf(1.0,2.0)\n",
"\n",
"\n",
"fun consumeList(l: List<Double>){\n",
" println(l)\n",
"}\n",
"\n",
"fun convertArrayToList(array: DoubleArray): List<Double> = array.asList()\/\/List(array.size){i -> array[i]}\n",
"\n",
"consumeList(convertArrayToList(array))"
],
"execution_count":25,
"outputs":[
{
"name":"stdout",
"text":[
"[1.0, 2.0]\n"
],
"output_type":"stream"
}
],
"metadata":{
"datalore":{
"node_id":"0r5gCS5ICD5utC3vtYhbOb",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"# Decorator?"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"jsc3UoWftQEDJuUInDWIpe",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"@JvmInline\n",
"value class EMail(val address: String)\n",
"\n",
"fun EMail.validate(): Boolean = TODO()\n",
"\n",
"val EMail.server get() = address.substringAfter(\"@\")"
],
"execution_count":27,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"cML7IAfXcFt8Aab6PWZ0z0",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"# Delegate"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"ibtt47bWffgOF3rAIxNuLO",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"class ValueHolder{\n",
" var value = 2\n",
"\n",
" fun printValue(){\n",
" println(value)\n",
" }\n",
"}\n",
"\n",
"ValueHolder().apply { value = 6 }.printValue()"
],
"execution_count":28,
"outputs":[
{
"name":"stdout",
"text":[
"6\n"
],
"output_type":"stream"
}
],
"metadata":{
"datalore":{
"node_id":"yvjapJUSD8MaI46U8mmlF4",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"Bad example"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"IGYgOEliyB7xhgQex6rTRS",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"class ModifiedValueHolder: ValueHolder(){\n",
" override fun printValue(){\n",
" print(\"value = \")\n",
" super.printValue()\n",
" }\n",
"}\n",
"\n",
"ModifiedValueHolder().apply { value = 6 }.printValue()"
],
"execution_count":29,
"outputs":[
{
"name":"stderr",
"text":[
"Line_141.jupyter.kts (1:28 - 39) This type is final, so it cannot be inherited from\n",
"Line_141.jupyter.kts (2:5 - 13) 'printValue' in 'ValueHolder' is final and cannot be overridden\n",
"Line_141.jupyter.kts (8:31 - 36) Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: \n",
"public final var value: Int defined in Line_141_jupyter.ModifiedValueHolder"
],
"output_type":"stream"
},
{
"ename":"Syntax Error",
"evalue":"Syntax Error: This type is final, so it cannot be inherited from",
"traceback":[
"\u001b[0;31m---------------------------------------------------------------------------",
"Traceback (most recent call last)",
"Syntax Error: This type is final, so it cannot be inherited from"
],
"output_type":"error"
}
],
"metadata":{
"datalore":{
"node_id":"m27RUUy8qf5jZllZknp5o3",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"class GoodValueHolder(val valueHolder: ValueHolder = ValueHolder()){\n",
"\n",
" var value by valueHolder::value\n",
"\n",
" fun printValue(){\n",
" print(\"value = \")\n",
" valueHolder.printValue()\n",
" }\n",
"}\n",
"GoodValueHolder().apply { value = 6 }.printValue()"
],
"execution_count":27,
"outputs":[
{
"name":"stdout",
"text":[
"value = 6\n"
],
"output_type":"stream"
}
],
"metadata":{
"datalore":{
"node_id":"OHLrIGtjkN2XQjYacDM8ut",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"class CompositeValueHolder(\n",
" val a: ValueHolder,\n",
" val b: ValueHolder\n",
"){\n",
" fun printValue(){\n",
" print(\"a = \")\n",
" a.printValue()\n",
" println()\n",
" print(\"b = \")\n",
" a.printValue()\n",
"\n",
" }\n",
"}"
],
"execution_count":null,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"fdNq2E5bTa6zarGwDDqQFj",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"class Id(val value: String)"
],
"execution_count":43,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"3OCnDlksXhltJds6fY0L7v",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"Id(\"d3d\").value"
],
"execution_count":44,
"outputs":[
{
"data":{
"text\/plain":[
"d3d"
]
},
"metadata":{},
"output_type":"display_data"
}
],
"metadata":{
"datalore":{
"node_id":"MjDAABWvcpMQLzBFN4x91C",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"Id(\"fff\").length"
],
"execution_count":41,
"outputs":[
{
"name":"stderr",
"text":[
"Line_154.jupyter-kts (1:11 - 17) Unresolved reference: length"
],
"output_type":"stream"
},
{
"ename":"Syntax Error",
"evalue":"Syntax Error: Unresolved reference: length",
"traceback":[
"\u001b[0;31m---------------------------------------------------------------------------",
"Traceback (most recent call last)",
"Syntax Error: Unresolved reference: length"
],
"output_type":"error"
}
],
"metadata":{
"datalore":{
"node_id":"525C4u3URrTwsBeZ2sTLud",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"# Proxy"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"NwAoDBrhHGOMQkkInhobM1",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"class StringProxy(val string: String): CharSequence by string{\n",
" override fun get(index: Int): Char{\n",
" return if(index < 0) '!' else string[index]\n",
" }\n",
"}"
],
"execution_count":30,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"x3XnwlrqMLxwzwughZSmqw",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"val proxy = StringProxy(\"dddd\")\n",
"\n",
"println(proxy[0])\n",
"println(proxy[-1])"
],
"execution_count":31,
"outputs":[
{
"name":"stdout",
"text":[
"d\n",
"!\n"
],
"output_type":"stream"
}
],
"metadata":{
"datalore":{
"node_id":"ZAprJIO0gNiM69lJSMgPVt",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"# Observer"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"xF2sXItrdeH2pbwchAI8UQ",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"class ObservableValueHolder(defaultValue: Int, val callback: (Int) -> Unit){\n",
" var value: Int = defaultValue\n",
" set(value){\n",
" field = value\n",
" callback(value)\n",
" }\n",
"}"
],
"execution_count":1,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"wLHHws3VLVqGyjA3YIdnaa",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"val holder = ObservableValueHolder(1){\n",
" println(\"Changed value = $it\")\n",
"}\n",
"holder.value = 6\n",
"holder.value = 7"
],
"execution_count":2,
"outputs":[
{
"name":"stdout",
"text":[
"Changed value = 6\n",
"Changed value = 7\n"
],
"output_type":"stream"
}
],
"metadata":{
"datalore":{
"node_id":"pAG4a8kqIeaClaAtAOOkwJ",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"# Visitor"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"0dpe5zY5a0RQW1ueDfxV4W",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"### Classic visitor"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"nePxZT9HQTU2lEhESlhVly",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"interface Structure\n",
"\n",
"class StringStructure(val string: String): Structure\n",
"\n",
"class IntStructure(val int: Int): Structure\n",
"\n",
"class StructureList(val content: List<Structure>): Structure"
],
"execution_count":13,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"Wo26AfHjCt8mlaZ2yIMcOm",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"fun interface StructureVisitor{\n",
" fun visit(structure: Structure): Unit\n",
"}\n",
"\n",
"val myStructureVisitor = object: StructureVisitor{\n",
" override fun visit(structure: Structure){\n",
" when(structure){\n",
" is StringStructure -> println(\"It is a StringStructure with value ${structure.string}\")\n",
" is IntStructure -> println(\"It is a IntStructure with value ${structure.int}\")\n",
" is StructureList -> structure.content.forEach{ visit(it) }\n",
" else -> println(\"I don't know what it is\")\n",
" }\n",
" }\n",
"}\n",
"\n",
"fun StructureList.visit(visitor: StructureVisitor){\n",
" visitor.visit(this)\n",
"}"
],
"execution_count":17,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"7ga1xsthc8oovIBmcC8Cg9",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"fun List<Structure>.asStructure() = StructureList(this)\n",
"\n",
"@JvmName(\"stringsAsStruct\")\n",
"fun List<String>.asStructure() = StructureList(map{StringStructure(it)})\n",
"\n",
"val structureList = StructureList(\n",
" listOf(\n",
" StringStructure(\"ddd\"),\n",
" IntStructure(2), \n",
" IntStructure(7),\n",
" listOf(\"aaa\", \"bbb\").asStructure()\n",
" )\n",
")\n",
"\n",
"structureList.visit(myStructureVisitor)"
],
"execution_count":24,
"outputs":[
{
"name":"stdout",
"text":[
"It is a StringStructure with value ddd\n",
"It is a IntStructure with value 2\n",
"It is a IntStructure with value 7\n",
"It is a StringStructure with value aaa\n",
"It is a StringStructure with value bbb\n"
],
"output_type":"stream"
}
],
"metadata":{
"datalore":{
"node_id":"lAzMMN1L3TmQl2cVxi36ED",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"### Kotlin idiomatic visiting"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"wvN4YCDwzYUDQfXA7IoRUr",
"type":"MD",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"sealed interface SealedStructure\n",
"\n",
"class StringSealedStructure(val string: String): SealedStructure\n",
"\n",
"class IntSealedStructure(val int: Int): SealedStructure"
],
"execution_count":27,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"GjXhhTAsHL0AUcEzmuypK1",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"fun List<SealedStructure>.visit(visitor: (SealedStructure) -> Unit){\n",
" forEach(visitor)\n",
"}"
],
"execution_count":28,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"p58da7MiEz4NeXbk2ZUyiz",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"val sealedStructureList = listOf<SealedStructure>(\n",
" StringSealedStructure(\"ddd\"),\n",
" IntSealedStructure(2), \n",
" IntSealedStructure(7),\n",
")\n",
"\n",
"sealedStructureList.visit{ structure ->\n",
" when(structure){\n",
" is StringSealedStructure -> println(\"It is a StringSealedStructure with value ${structure.string}\")\n",
" is IntSealedStructure -> println(\"It is a IntSealedStructure with value ${structure.int}\")\n",
" else -> {} \/\/ why is that?\n",
" }\n",
"}"
],
"execution_count":30,
"outputs":[
{
"name":"stderr",
"text":[
"Line_206.jupyter.kts (8:5 - 9) 'when' expression must be exhaustive, add necessary 'else' branch"
],
"output_type":"stream"
},
{
"ename":"Syntax Error",
"evalue":"Syntax Error: 'when' expression must be exhaustive, add necessary 'else' branch",
"traceback":[
"\u001b[0;31m---------------------------------------------------------------------------",
"Traceback (most recent call last)",
"Syntax Error: 'when' expression must be exhaustive, add necessary 'else' branch"
],
"output_type":"error"
}
],
"metadata":{
"datalore":{
"node_id":"aCfKGNanITfEocl3N0T0Ce",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[],
"execution_count":null,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"EmfBYCTjDyjeCP4LqTIyFg",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"markdown",
"source":[
"# Observer"
],
"attachments":{},
"metadata":{
"datalore":{
"node_id":"Observer",
"type":"MD",
"hide_input_from_viewers":false,
"hide_output_from_viewers":false,
"sheet_delimiter":true
}
}
},
{
"cell_type":"code",
"source":[
"import kotlin.properties.Delegates\n",
"\n",
"class ObservableHolder{\n",
" var observable: Int by Delegates.observable<Int>(1){ property, oldValue, newValue ->\n",
" println(\"${property.name} $newValue\")\n",
" }\n",
"}"
],
"execution_count":8,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"h2OYBThfWjdp7hhteNH2Lt",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"val holder = ObservableHolder()\n",
"\n",
"holder.observable = 5"
],
"execution_count":9,
"outputs":[
{
"name":"stdout",
"text":[
"observable 5\n"
],
"output_type":"stream"
}
],
"metadata":{
"datalore":{
"node_id":"pAzvJyJubYwBrzqNmGLAMj",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[
"class Response(val header: String, val body: () -> String ){\n",
" fun onRead(callback: (String) -> Unit){\n",
" callback(body())\n",
" }\n",
"}\n",
"\n",
"class Call(val request: String, val onResponse: (Response) -> Unit){\n",
" fun start(){\n",
" onResponse(Response(\"header\"){\"body\"})\n",
" }\n",
"}\n",
"\n",
"Call(\"spc\"){ response->\n",
" println(response.header)\n",
" response.onRead{ body->\n",
" println(body)\n",
" }\n",
"}.start()"
],
"execution_count":12,
"outputs":[
{
"name":"stdout",
"text":[
"header\n",
"body\n"
],
"output_type":"stream"
}
],
"metadata":{
"datalore":{
"node_id":"z4D2hzOyzy2Dmpi1QbKMqf",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
},
{
"cell_type":"code",
"source":[],
"execution_count":null,
"outputs":[],
"metadata":{
"datalore":{
"node_id":"QlpqRBkqqUHN2CUAm2hP3H",
"type":"CODE",
"hide_input_from_viewers":true,
"hide_output_from_viewers":true
}
}
}
],
"metadata":{
"kernelspec":{
"display_name":"Kotlin",
"language":"kotlin",
"name":"kotlin"
},
"datalore":{
"computation_mode":"JUPYTER",
"package_manager":"pip",
"base_environment":"default",
"packages":[],
"report_row_ids":[],
"version":3
}
},
"nbformat":4,
"nbformat_minor":4
}