diff --git a/build.gradle b/build.gradle index dcb6872..f6bdb89 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ plugins { id 'org.jetbrains.kotlin.jvm' version '2.2.10' + id 'application' } kotlin { @@ -13,6 +14,10 @@ test { group 'ru.otus' version '1.0-SNAPSHOT' +application { + mainClass = 'ru.otus.homework.homework.MainKt' +} + repositories { mavenCentral() } diff --git a/src/main/kotlin/ru/otus/homework/homework/Coffee.kt b/src/main/kotlin/ru/otus/homework/homework/Coffee.kt index c73f420..39922cc 100644 --- a/src/main/kotlin/ru/otus/homework/homework/Coffee.kt +++ b/src/main/kotlin/ru/otus/homework/homework/Coffee.kt @@ -20,32 +20,30 @@ 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 CoffeeDecorator( + private val coffee: Coffee, + private val ingredientCost: Int, + private val ingredientDescription: String, +) : Coffee { + override fun cost(): Int = coffee.cost() + ingredientCost + + override fun description(): String = "${coffee.description()}, $ingredientDescription" } -class SugarDecorator(private val coffee: Coffee) : Coffee { - override fun cost(): Int { - TODO("Not yet implemented") - } - - override fun description(): String { - TODO("Not yet implemented") - } -} - -class VanillaDecorator(private val coffee: Coffee) : Coffee { - override fun cost(): Int { - TODO("Not yet implemented") - } - - override fun description(): String { - TODO("Not yet implemented") - } -} \ No newline at end of file +class MilkDecorator(coffee: Coffee) : CoffeeDecorator( + coffee = coffee, + ingredientCost = 50, + ingredientDescription = "молоко", +) + +class SugarDecorator(coffee: Coffee) : CoffeeDecorator( + coffee = coffee, + ingredientCost = 20, + ingredientDescription = "сахар", +) + +class VanillaDecorator(coffee: Coffee) : CoffeeDecorator( + coffee = coffee, + ingredientCost = 70, + ingredientDescription = "ваниль", +) \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/homework/homework/Main.kt b/src/main/kotlin/ru/otus/homework/homework/Main.kt new file mode 100644 index 0000000..3d27080 --- /dev/null +++ b/src/main/kotlin/ru/otus/homework/homework/Main.kt @@ -0,0 +1,64 @@ +package ru.otus.homework.homework + +fun main() { + printInlineTask() + printCoffeeTask() + printUserProfileTask() + printLoggingUserProfileTask() +} + +private fun printInlineTask() { + println("Задание 1") + println("Список: 1, 2, 3, 4") + println("Результат:") + skipThreeAndPrint(listOf(1, 2, 3, 4)) + println() +} + +private fun printCoffeeTask() { + println("Задание 2") + + val simpleCoffee = SimpleCoffee() + val coffeeWithMilk = MilkDecorator(SimpleCoffee()) + val coffeeWithMilkAndSugar = SugarDecorator(coffeeWithMilk) + val coffeeWithAllIngredients = VanillaDecorator(coffeeWithMilkAndSugar) + + printCoffee("Кофе", simpleCoffee) + printCoffee("С молоком", coffeeWithMilk) + printCoffee("С молоком и сахаром", coffeeWithMilkAndSugar) + printCoffee("Все добавки", coffeeWithAllIngredients) + println() +} + +private fun printCoffee(title: String, coffee: Coffee) { + println("$title: ${coffee.description()}, цена ${coffee.cost()} коп.") +} + +private fun printUserProfileTask() { + println("Задание 3") + + val user = UserProfile.create("Andrey", "andrey@andreymail.com") + println("Профиль: fullName='${user.fullName}', email='${user.email}'") + + user.fullName = "Andrey 2" + user.email = "andrey2@andreymail.com" + println("Результат: fullName='${user.fullName}', email='${user.email}'") + + user.fullName = " " + user.email = "прпрпрп" + println("Результат (не изменились): fullName='${user.fullName}', email='${user.email}'") + println() +} + +private fun printLoggingUserProfileTask() { + println("Профиль с логированием") + val user = UserProfile.createWithLogging("Andrey", "andrey@andreymail.com") + user.fullName = "Andrey 3" + user.email = "andrey3@andreymail.com" + user.fullName = "" + user.email = "ывывывы" + + println("Результат: fullName='${user.fullName}', email='${user.email}'") + println("Журнал изменений:") + user.getLog().forEach { println(it) } +} \ 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..a1525ce 100644 --- a/src/main/kotlin/ru/otus/homework/homework/NonEmptyStringDelegate.kt +++ b/src/main/kotlin/ru/otus/homework/homework/NonEmptyStringDelegate.kt @@ -5,12 +5,16 @@ import kotlin.reflect.KProperty /** * Delegate that allows to set non-empty string value */ -class NonEmptyStringDelegate() { +class NonEmptyStringDelegate { + private var value = "" + 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()) { + value = newValue + } } } \ 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..5f1081c 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.properties.Delegates + /** * Профиль пользователя */ @@ -37,7 +39,7 @@ interface UserProfile { * Creates user profile with logging */ fun createWithLogging(fullName: String, email: String): UserProfile.Logging { - TODO("Implement `createWithLogging` function") + return LoggingProfileImplementation(create(fullName, email)) } } } @@ -50,4 +52,42 @@ 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 { + override var fullName: String by NonEmptyStringDelegate() + + override var email: String by Delegates.vetoable(email) { _, _, newValue -> + newValue.isNotBlank() && emailRegex.matches(newValue) + } + + init { + this.fullName = fullName + } +} + +private class LoggingProfileImplementation( + private val userProfile: UserProfile, +) : UserProfile.Logging, UserProfile by userProfile { + private val log = mutableListOf() + + override var fullName: String + get() = userProfile.fullName + set(value) { + val oldValue = userProfile.fullName + userProfile.fullName = value + if (userProfile.fullName != oldValue) { + log += "Изменение `fullName` с '$oldValue' на '${userProfile.fullName}'" + } + } + + override var email: String + get() = userProfile.email + set(value) { + val oldValue = userProfile.email + userProfile.email = value + if (userProfile.email != oldValue) { + log += "Изменение `email` с '$oldValue' на '${userProfile.email}'" + } + } + + override fun getLog(): List = log.toList() +} 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") } }