diff --git a/build.gradle b/build.gradle index dcb6872..df07d71 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'org.jetbrains.kotlin.jvm' version '2.2.10' + id 'org.jetbrains.kotlin.jvm' version '2.0.21' } kotlin { diff --git a/src/main/kotlin/ru/otus/homework/homework/Coffee.kt b/src/main/kotlin/ru/otus/homework/homework/Coffee.kt index c73f420..f199a1b 100644 --- a/src/main/kotlin/ru/otus/homework/homework/Coffee.kt +++ b/src/main/kotlin/ru/otus/homework/homework/Coffee.kt @@ -20,32 +20,26 @@ class SimpleCoffee : Coffee { override fun description() = "Простой кофе" } -class MilkDecorator(private val coffee: Coffee) : Coffee { - override fun cost(): Int { - TODO("Not yet implemented") - } - - override fun description(): String { - TODO("Not yet implemented") - } -} +// Абстрактный базовый класс для декораций +abstract class AbstractDecorator(protected val decoratedCoffee: Coffee) : Coffee { + protected abstract val additionalCost: Int + protected abstract val additionalDescription: String -class SugarDecorator(private val coffee: Coffee) : Coffee { - override fun cost(): Int { - TODO("Not yet implemented") - } + final override fun cost() = decoratedCoffee.cost() + additionalCost + final override fun description() = "${decoratedCoffee.description()}, $additionalDescription" +} - override fun description(): String { - TODO("Not yet implemented") - } +class MilkDecorator(coffee: Coffee) : AbstractDecorator(coffee) { + override val additionalCost = 50 + override val additionalDescription = "молоко" } -class VanillaDecorator(private val coffee: Coffee) : Coffee { - override fun cost(): Int { - TODO("Not yet implemented") - } +class SugarDecorator(decoratedCoffee: Coffee) : AbstractDecorator(decoratedCoffee) { + override val additionalCost = 20 + override val additionalDescription = "сахар" +} - override fun description(): String { - TODO("Not yet implemented") - } +class VanillaDecorator(decoratedCoffee: Coffee) : AbstractDecorator(decoratedCoffee) { + override val additionalCost = 70 + override val additionalDescription = "ваниль" } \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/homework/homework/NonEmptyStringDelegate.kt b/src/main/kotlin/ru/otus/homework/homework/NonEmptyStringDelegate.kt index 568f368..4161a0b 100644 --- a/src/main/kotlin/ru/otus/homework/homework/NonEmptyStringDelegate.kt +++ b/src/main/kotlin/ru/otus/homework/homework/NonEmptyStringDelegate.kt @@ -1,16 +1,23 @@ package ru.otus.homework.homework + import kotlin.reflect.KProperty /** * Delegate that allows to set non-empty string value */ class NonEmptyStringDelegate() { + private var value: String = "" + operator fun getValue(thisRef: Any?, property: KProperty<*>): String { - TODO("Implement `getValue` function") + return value } operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) { - TODO("Implement `setValue` function") + if (newValue.isNotBlank()) { + this.value = newValue + } else { + System.err.println("Property ${property.name} cannot be empty") + } } } \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/homework/homework/UserProfile.kt b/src/main/kotlin/ru/otus/homework/homework/UserProfile.kt index f0fab82..660d116 100644 --- a/src/main/kotlin/ru/otus/homework/homework/UserProfile.kt +++ b/src/main/kotlin/ru/otus/homework/homework/UserProfile.kt @@ -2,6 +2,8 @@ package ru.otus.homework.homework +import kotlin.reflect.KProperty + /** * Профиль пользователя */ @@ -37,7 +39,9 @@ interface UserProfile { * Creates user profile with logging */ fun createWithLogging(fullName: String, email: String): UserProfile.Logging { - TODO("Implement `createWithLogging` function") + return ProfileImplementationWithLogging( + create(fullName, email) + ) } } } @@ -50,4 +54,57 @@ private val emailRegex = Regex("^[A-Za-z](.*)([@])(.+)(\\.)(.+)") /** * Реализация простого [UserProfile]. */ -private class ProfileImplementation(override var fullName: String, override var email: String): UserProfile \ No newline at end of file +private class ProfileImplementation( + fullName: String, + email: String +) : UserProfile { + val vetoable = VetoableEmail() + val nonEmptyStringDelegate = NonEmptyStringDelegate() + override var fullName: String by nonEmptyStringDelegate + override var email: String by vetoable + + init { + this.fullName = fullName + this.email = email + } + +} + +/** + * Реализация [UserProfile.Logging]. + */ +private class ProfileImplementationWithLogging( + val userProfile: UserProfile +) : UserProfile.Logging, UserProfile by userProfile { + private val log = mutableListOf() + + override var fullName: String + get() = userProfile.fullName + set(value) { + log.add("Changing `fullName` from '${userProfile.fullName}' to '$value'") + userProfile.fullName = value + } + + override var email: String + get() = userProfile.email + set(value) { + log.add("Changing `email` from '${userProfile.email}' to '$value'") + userProfile.email = value + } + + override fun getLog(): List = log +} + +class VetoableEmail { + var email: String = "" + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { + if (value.matches(emailRegex)) + email = value + else + System.err.println("veto placed on invalid email $value") + } + + operator fun getValue(hisRef: Any?, property: KProperty<*>): String { + return this.email + } +} \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/homework/homework/processList.kt b/src/main/kotlin/ru/otus/homework/homework/processList.kt index 6d8ab43..fa9940e 100644 --- a/src/main/kotlin/ru/otus/homework/homework/processList.kt +++ b/src/main/kotlin/ru/otus/homework/homework/processList.kt @@ -8,7 +8,7 @@ inline fun processList(list: List, action: (Int) -> Unit) { fun skipThreeAndPrint(list: List) { processList(list) { - if (it == 3) return + if (it == 3) return@processList println("Processing $it") } }