27 KiB
27 KiB
Sheet¶
Factories¶
In [ ]:
interface A{ val body: String } class B(override val body: String): A{ override fun toString() = "$body B" } class C(override val body: String): A{ override fun toString() = "$body C" } fun print(obj: A){ println(obj) }
In [ ]:
print(C("My body"))
In [ ]:
interface AFactory<out T: A>{ fun create(body: String): T } object BFactory: AFactory<B>{ override fun create(body: String): B = B(body) } fun <T: A> createWithAWord(word: String, factory: AFactory<T>) = factory.create("Word: $word")
In [ ]:
createWithAWord("Hello", BFactory)
In [ ]:
fun <T: A> createWithAWord(word: String, factoryFunction: (String) -> T) = factoryFunction("Word: $word")
In [ ]:
createWithAWord("Hello", ::B)
In [ ]:
createWithAWord("Hello"){body -> B(">\t$body")}
Factory functions¶
In [ ]:
data class Client(val url: String) interface Request{ val client: Client } data class RequestImpl(override val client: Client): Request{ // constructor(url: String): this(Client(url)) }
In [ ]:
fun Request(url: String): Request{ return RequestImpl(Client(url)) }
In [ ]:
Request("DDD")
In [ ]:
listOf(1,2,3)
Lazy¶
In [ ]:
class WithLazy{ val prop = 2 get(){ println("Hit $field") return field } val lazyProp by lazy{ println("Hit lazy") 2 } }
In [ ]:
val withLazy = WithLazy()
In [ ]:
withLazy.prop withLazy.prop withLazy.prop
In [ ]:
withLazy.lazyProp withLazy.lazyProp withLazy.lazyProp
Builder¶
In [ ]:
data class Buildable( var a: Int = 1, var b: Int = 2, var c: Int = 3 ){ fun setABC(value: Int){ a = value b = value c = value } } // Buildable.builder() // .setA(1) // .setB(2) // .setC(3) // .setABC(1) // .build()
In [ ]:
Buildable(b = 5)
In [ ]:
Buildable().apply { a = 1 setABC(a + b + c) }
In [ ]:
fun Buildable(block: Buildable.()-> Unit): Buildable = Buildable().apply(block) Buildable{ a = 1 setABC(a + b + c) }
Multiton¶
In [ ]:
class Multiton private constructor(val name: String){ init{ println("Multiton $name created") } companion object { private val cache = HashMap<String, Multiton>() fun resolve(name: String) = cache.getOrPut(name){Multiton(name)} } }
In [ ]:
Multiton.resolve("a") Multiton.resolve("a") Multiton.resolve("b") Multiton.resolve("a")
In [ ]:
Multiton("v")
In [ ]:
sealed interface SealedMultiton{ object A: SealedMultiton object B: SealedMultiton class Custom(val body: String): SealedMultiton } fun evaluateSealedMultiton(sealed: SealedMultiton) = when(sealed){ is SealedMultiton.A-> println("A") is SealedMultiton.B-> println("B") is SealedMultiton.Custom -> println(sealed.body) }
Adapter¶
In [ ]:
val array = doubleArrayOf(1.0,2.0) val list = listOf(1.0,2.0) fun consumeList(l: List<Double>){ println(l) } fun convertArrayToList(array: DoubleArray): List<Double> = array.asList()//List(array.size){i -> array[i]} consumeList(convertArrayToList(array))
Decorator?¶
In [ ]:
@JvmInline value class EMail(val address: String) fun EMail.validate(): Boolean = TODO() val EMail.server get() = address.substringAfter("@")
Delegate¶
In [ ]:
class ValueHolder{ var value = 2 fun printValue(){ println(value) } } ValueHolder().apply { value = 6 }.printValue()
Bad example
In [ ]:
class ModifiedValueHolder: ValueHolder(){ override fun printValue(){ print("value = ") super.printValue() } } ModifiedValueHolder().apply { value = 6 }.printValue()
In [ ]:
class GoodValueHolder(val valueHolder: ValueHolder = ValueHolder()){ var value by valueHolder::value fun printValue(){ print("value = ") valueHolder.printValue() } } GoodValueHolder().apply { value = 6 }.printValue()
In [ ]:
class CompositeValueHolder( val a: ValueHolder, val b: ValueHolder ){ fun printValue(){ print("a = ") a.printValue() println() print("b = ") a.printValue() } }
In [ ]:
class Id(val value: String)
In [ ]:
Id("d3d").value
In [ ]:
Id("fff").length
Proxy¶
In [ ]:
class StringProxy(val string: String): CharSequence by string{ override fun get(index: Int): Char{ return if(index < 0) '!' else string[index] } }
In [ ]:
val proxy = StringProxy("dddd") println(proxy[0]) println(proxy[-1])
Observer¶
In [ ]:
class ObservableValueHolder(defaultValue: Int, val callback: (Int) -> Unit){ var value: Int = defaultValue set(value){ field = value callback(value) } }
In [ ]:
val holder = ObservableValueHolder(1){ println("Changed value = $it") } holder.value = 6 holder.value = 7
Visitor¶
Classic visitor¶
In [ ]:
interface Structure class StringStructure(val string: String): Structure class IntStructure(val int: Int): Structure class StructureList(val content: List<Structure>): Structure
In [ ]:
fun interface StructureVisitor{ fun visit(structure: Structure): Unit } val myStructureVisitor = object: StructureVisitor{ override fun visit(structure: Structure){ when(structure){ is StringStructure -> println("It is a StringStructure with value ${structure.string}") is IntStructure -> println("It is a IntStructure with value ${structure.int}") is StructureList -> structure.content.forEach{ visit(it) } else -> println("I don't know what it is") } } } fun StructureList.visit(visitor: StructureVisitor){ visitor.visit(this) }
In [ ]:
fun List<Structure>.asStructure() = StructureList(this) @JvmName("stringsAsStruct") fun List<String>.asStructure() = StructureList(map{StringStructure(it)}) val structureList = StructureList( listOf( StringStructure("ddd"), IntStructure(2), IntStructure(7), listOf("aaa", "bbb").asStructure() ) ) structureList.visit(myStructureVisitor)
Kotlin idiomatic visiting¶
In [ ]:
sealed interface SealedStructure class StringSealedStructure(val string: String): SealedStructure class IntSealedStructure(val int: Int): SealedStructure
In [ ]:
fun List<SealedStructure>.visit(visitor: (SealedStructure) -> Unit){ forEach(visitor) }
In [ ]:
val sealedStructureList = listOf<SealedStructure>( StringSealedStructure("ddd"), IntSealedStructure(2), IntSealedStructure(7), ) sealedStructureList.visit{ structure -> when(structure){ is StringSealedStructure -> println("It is a StringSealedStructure with value ${structure.string}") is IntSealedStructure -> println("It is a IntSealedStructure with value ${structure.int}") else -> {} // why is that? } }
In [ ]:
Observer¶
In [ ]:
import kotlin.properties.Delegates class ObservableHolder{ var observable: Int by Delegates.observable<Int>(1){ property, oldValue, newValue -> println("${property.name} $newValue") } }
In [ ]:
val holder = ObservableHolder() holder.observable = 5
In [ ]:
class Response(val header: String, val body: () -> String ){ fun onRead(callback: (String) -> Unit){ callback(body()) } } class Call(val request: String, val onResponse: (Response) -> Unit){ fun start(){ onResponse(Response("header"){"body"}) } } Call("spc"){ response-> println(response.header) response.onRead{ body-> println(body) } }.start()
In [ ]: