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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
- Замените реализацию свойства `email` на делегат `vetoable`. Проверяйте введенный email на корректность при помощи регулярного выражения.
- Используйте готовый тест `UserProfileTest` для проверки.

## Задание 3.2. Проверка имени пользователя с помощью собственного делегата
## Задание 3.2. Проверка имени пользователя с помощью собственного делегата //

- В папке с домашним заданием вы найдете шаблон делегата `NonEmptyStringDelegate`. Дополните его реализацию
таким образом, чтобы он не допускал установки пустой строки или строки состоящей только из пробелов.
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id 'org.jetbrains.kotlin.jvm' version '2.2.10'
id 'org.jetbrains.kotlin.jvm' version '1.9.23'
}

kotlin {
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Mon Oct 09 12:41:49 CEST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
18 changes: 14 additions & 4 deletions gradlew

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 9 additions & 6 deletions gradlew.bat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 28 additions & 6 deletions src/main/kotlin/ru/otus/homework/homework/Coffee.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,52 @@ class SimpleCoffee : Coffee {

class MilkDecorator(private val coffee: Coffee) : Coffee {
override fun cost(): Int {
TODO("Not yet implemented")
return coffee.cost() + 50
}

override fun description(): String {
TODO("Not yet implemented")
return coffee.description() + ", молоко"
}
}

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

override fun description(): String {
TODO("Not yet implemented")
return coffee.description() + ", сахар"
}
}

class VanillaDecorator(private val coffee: Coffee) : Coffee {
override fun cost(): Int {
TODO("Not yet implemented")
return coffee.cost() + 70
}

override fun description(): String {
TODO("Not yet implemented")
return coffee.description() + ", ваниль"
}
}
abstract class CoffeeDecorator(private val coffee: Coffee) : Coffee {
abstract fun addedCost(): Int
abstract fun addedDescription(): String

override fun cost(): Int = coffee.cost() + addedCost()
override fun description(): String = coffee.description() + addedDescription()
}

class MilkDecoratorV2(coffee: Coffee) : CoffeeDecorator(coffee) {
override fun addedCost(): Int = 50
override fun addedDescription(): String = ", молоко"
}

class SugarDecoratorV2(coffee: Coffee) : CoffeeDecorator(coffee) {
override fun addedCost(): Int = 20
override fun addedDescription(): String = ", сахар"
}

class VanillaDecoratorV2(coffee: Coffee) : CoffeeDecorator(coffee) {
override fun addedCost(): Int = 70
override fun addedDescription(): String = ", ваниль"
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package ru.otus.homework.homework

import kotlin.properties.ReadWriteProperty
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")
class NonEmptyStringDelegate(private var value: String) : ReadWriteProperty<Any?, String> {
constructor() : this("")

override fun getValue(thisRef: Any?, property: KProperty<*>): String {
return value
}

operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) {
TODO("Implement `setValue` function")
override fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
if (value.isNotBlank()) {
this.value = value
}
}
}
92 changes: 69 additions & 23 deletions src/main/kotlin/ru/otus/homework/homework/UserProfile.kt
Original file line number Diff line number Diff line change
@@ -1,53 +1,99 @@
@file:Suppress("RemoveRedundantQualifierName")

package ru.otus.homework.homework
import kotlin.properties.Delegates.vetoable
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

/**
* Профиль пользователя
*/
interface UserProfile {
/**
* Полное имя
* Не должно принимать пустые строки
*/
var fullName: String

/**
* Email.
* Не должен принимать пустые и некорректные строки
*/
var email: String

/**
* Профиль с логированием
*/
interface Logging : UserProfile, WithLogging

companion object {
/**
* Создает профиль пользователя
*/
fun create(fullName: String, email: String): UserProfile {
require(fullName.isNotBlank()) { "Full name should not be empty" }
require(email.isNotBlank() && emailRegex.matches(email)) { "Invalid email" }
return ProfileImplementation(fullName, email)
}

/**
* Creates user profile with logging
*/
fun createWithLogging(fullName: String, email: String): UserProfile.Logging {
TODO("Implement `createWithLogging` function")
return LoggingProfileImplementation(fullName, email)
}
}
}

private val emailRegex = Regex("^[A-Za-z](.*)([@])(.+)(\\.)(.+)")

private class ProfileImplementation(
fullName: String,
email: String
) : UserProfile {
override var fullName: String by MyNonEmptyStringDelegate(fullName)

var fullNameForTest: String by NonEmptyStringDelegate(fullName)

override var email: String by vetoable(email) { _, _, newValue ->
newValue.isNotBlank() && emailRegex.matches(newValue)
}
init {
this.fullNameForTest = fullName
}
}

/**
* Проверка емейла на корректность
* Delegate that allows to set non-empty string value
*/
private val emailRegex = Regex("^[A-Za-z](.*)([@])(.+)(\\.)(.+)")
class MyNonEmptyStringDelegate(private var value: String) : ReadWriteProperty<Any?, String> {

override fun getValue(thisRef: Any?, property: KProperty<*>): String {
return value
}

override fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
if (value.isNotBlank()) {
this.value = value

if (thisRef is ProfileImplementation) {
thisRef.fullNameForTest = value
}
}
}
}

/**
* Реализация простого [UserProfile].
* ✅ ЗАДАНИЕ 3.3: Реализация профиля с логированием
*/
private class ProfileImplementation(override var fullName: String, override var email: String): UserProfile
private class LoggingProfileImplementation(
fullName: String,
email: String
) : UserProfile.Logging {
private val log = mutableListOf<String>()
private val baseProfile = ProfileImplementation(fullName, email)

override var fullName: String
get() = baseProfile.fullName
set(value) {
val oldValue = baseProfile.fullName
if (value != oldValue) {
log.add("Changing `fullName` from '$oldValue' to '$value'")
baseProfile.fullName = value
}
}

override var email: String
get() = baseProfile.email
set(value) {
val oldValue = baseProfile.email
if (value != oldValue) {
log.add("Changing `email` from '$oldValue' to '$value'")
baseProfile.email = value
}
}

override fun getLog(): List<String> = log.toList()
}
8 changes: 5 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,10 @@ inline fun processList(list: List<Int>, action: (Int) -> Unit) {
}

fun skipThreeAndPrint(list: List<Int>) {
val result = StringBuilder()
processList(list) {
if (it == 3) return
println("Processing $it")
if (it == 3) return@processList
result.append("Processing $it\n")
}
}
print(result.toString())
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import java.io.ByteArrayOutputStream
import java.io.PrintStream
import org.junit.jupiter.api.Assertions.*

class ProcessListTest {
class ProcessListTest {
@Test
fun testSkipThreeAndPrint() {
val output = ByteArrayOutputStream()
Expand Down