Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 13 additions & 23 deletions src/main/kotlin/ru/otus/homework/homework/Coffee.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,22 @@ 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 DecoratorCoffee(private val coffee: Coffee): Coffee{
override fun cost() = coffee.cost()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dbulygin, тут все хорошо, но, КМК, можно улучшить и убрать дублирование логики у детей. Мы всегда прибавляем цифры и строки, поэтому

abstract class DecoratorCoffee(private val coffee: Coffee): Coffee{
    abstract val extraCost: Int
    abstract val extraDesc: String

    override fun cost() = coffee.cost() + extraCost
    override fun description() = "${coffee.description()}, $extraDesc"
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это красиво, я не додумался

override fun description() = coffee.description()
}

class SugarDecorator(private val coffee: Coffee) : Coffee {
override fun cost(): Int {
TODO("Not yet implemented")
}

override fun description(): String {
TODO("Not yet implemented")
}
class MilkDecorator(private val coffee: Coffee) : DecoratorCoffee(coffee) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dbulygin , и тут, согласно верхнему:

class MilkDecorator(coffee: Coffee) : DecoratorCoffee(coffee) {
    override val extraCost: Int = 50
    override val extraDesc: String = "Milk"
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Так выглядит намного чище, и в декораторе спрятана логика 🤝

override fun cost() = super.cost() + 50
override fun description() = super.description() + ", молоко"
}

class VanillaDecorator(private val coffee: Coffee) : Coffee {
override fun cost(): Int {
TODO("Not yet implemented")
}
class SugarDecorator(private val coffee: Coffee) : DecoratorCoffee(coffee) {
override fun cost() = super.cost() + 20
override fun description() = super.description() + ", сахар"
}

override fun description(): String {
TODO("Not yet implemented")
}
class VanillaDecorator(private val coffee: Coffee) : DecoratorCoffee(coffee) {
override fun cost() = super.cost() + 70
override fun description() = super.description() + ", ваниль"
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,21 @@ import kotlin.reflect.KProperty
* Delegate that allows to set non-empty string value
*/
class NonEmptyStringDelegate() {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
TODO("Implement `getValue` function")
private var value: String = ""

// если модифицровать конструктор NonEmptyStringDelegate, было бы проще..
fun init(initValue: String) {
value = initValue
}

operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) {
TODO("Implement `setValue` function")
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return value
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
if (value.isNotBlank()) {
this.value = value
} else {
println("empty fullname")
}
}
}
58 changes: 56 additions & 2 deletions src/main/kotlin/ru/otus/homework/homework/UserProfile.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@file:Suppress("RemoveRedundantQualifierName")

package ru.otus.homework.homework
import kotlin.properties.Delegates

/**
* Профиль пользователя
Expand All @@ -27,6 +28,7 @@ interface UserProfile {
/**
* Создает профиль пользователя
*/
//override var email: String by Delegates.vetoable()
fun create(fullName: String, email: String): UserProfile {
require(fullName.isNotBlank()) { "Full name should not be empty" }
require(email.isNotBlank() && emailRegex.matches(email)) { "Invalid email" }
Expand All @@ -37,7 +39,7 @@ interface UserProfile {
* Creates user profile with logging
*/
fun createWithLogging(fullName: String, email: String): UserProfile.Logging {
TODO("Implement `createWithLogging` function")
return LoggingProfile(fullName, email)
}
}
}
Expand All @@ -50,4 +52,56 @@ private val emailRegex = Regex("^[A-Za-z](.*)([@])(.+)(\\.)(.+)")
/**
* Реализация простого [UserProfile].
*/
private class ProfileImplementation(override var fullName: String, override var email: String): UserProfile
private class ProfileImplementation(initFullNAme: String, initEmail: String): UserProfile {
override var email: String by Delegates.vetoable(initEmail) { _, old, new ->
when {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dbulygin , matches уже возвращает Boolean. Поэтому, для лучшей читаемости можно написать:

override var email: String by Delegates.vetoable(initEmail) { _, old, new ->
        emailRegex.matches(new)
}

!emailRegex.matches(new) -> {
false
}

else -> true
}
}

// если бы можно было переделать конструктор NonEmptyStringDelegate(),
// было бы проще с передачей значения
private val fullNameDelegate = NonEmptyStringDelegate().apply {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dbulygin, можно.
Делегат:

class NonEmptyStringDelegate(private var value: String = "") {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return value
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) {
        value = newValue.ifBlank { value }
    }
}

Профиль:

private class ProfileImplementation(fullName: String, email: String): UserProfile {

    override var fullName: String by NonEmptyStringDelegate(fullName)

    override var email: String by Delegates.vetoable(email) { _, _, new ->
        new.isNotBlank() && emailRegex.matches(new)
    }
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А что я постеснялся.. 😁
Спасибо!

init(initFullNAme)
}
override var fullName: String by fullNameDelegate
}

private class LoggingProfile(initFullName: String, initEmail: String) : UserProfile.Logging {
private val logs = mutableListOf<String>()

override fun getLog(): List<String> = logs.toList()

private val fullNameDelegate = NonEmptyStringDelegate().apply {
init(initFullName)
}
override var fullName: String
get() = fullNameDelegate.getValue(this, ::fullName)
set(value) {
val oldValue = fullName
fullNameDelegate.setValue(this, ::fullName, value)
if (fullName != oldValue) {
addLog("Changing `fullName` from '$oldValue' to '$fullName'")
} else {
addLog("Bad FullName: $fullName")
}
}

override var email: String by Delegates.vetoable(initEmail) { _, old, new ->
val isValid = emailRegex.matches(new)
if (isValid) {
addLog("Changing `email` from '$old' to '$new'")
} else {
addLog("Bad email: $new")
}
isValid
}

private fun addLog(message: String) {
logs.add(message)
}
}
12 changes: 9 additions & 3 deletions src/main/kotlin/ru/otus/homework/homework/processList.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@ inline fun processList(list: List<Int>, action: (Int) -> Unit) {
}

fun skipThreeAndPrint(list: List<Int>) {
var counter = 1
processList(list) {
if (it == 3) return
println("Processing $it")
if (counter != 3)
/* тут пришлось помучиться,
* т.к. тесты НЕ проходили, если использовать функцию println()
* пришлось переключиться на print(...\n)
*/
print("Processing $it\n")
counter ++
}
}
}