0Pricing
Kotlin Academy · Урок

Варианты использования

Моделирование предметной области

«Варианты использования» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.

Моделирование предметной области

Классы-значения особенно полезны при моделировании предметной области. Они превращают безымянные примитивы в осмысленные типы, защищённые от ошибок, без затрат во время выполнения.

Рассмотрим реалистичные сценарии.

Типизированные идентификаторы

Отдельные типы идентификаторов не позволяют передать идентификатор пользователя туда, где нужен идентификатор заказа, — это распространённая и дорогостоящая ошибка.

@JvmInline
value class UserId(val value: Long)
@JvmInline
value class OrderId(val value: Long)

fun fetchUser(id: UserId) = "user " + id.value

fun main() {
    println(fetchUser(UserId(7)))
}

Единицы измерения

Обёртка чисел в типы единиц измерения не позволяет случайно сложить метры с секундами и одновременно поясняет смысл значения.

@JvmInline
value class Kilograms(val value: Double)

fun describe(weight: Kilograms) = weight.value.toString() + " kg"

fun main() {
    println(describe(Kilograms(72.5)))
}

Проверяемые строки

Сочетайте класс-значение с блоком init, чтобы гарантировать инварианты, например отсутствие пробелов в адресе электронной почты.

@JvmInline
value class Email(val value: String) {
    init {
        require(value.contains("@")) { "invalid email" }
    }
}

fun main() {
    println(Email("a@b.com").value)
}

Деньги с поведением

Представляйте деньги в наименьших единицах и добавляйте операции над ними, избегая ошибок с плавающей точкой при работе с валютой.

@JvmInline
value class Cents(val value: Long) {
    operator fun plus(other: Cents) = Cents(value + other.value)
    fun format() = "$" + value / 100.0
}

fun main() {
    val total = Cents(1500) + Cents(250)
    println(total.format())
}

Самодокументируемые интерфейсы

Сигнатура функции с классами-значениями гораздо понятнее сигнатуры с тремя несвязанными целыми числами.

@JvmInline
value class Width(val px: Int)
@JvmInline
value class Height(val px: Int)

fun area(w: Width, h: Height) = w.px * h.px

fun main() {
    println(area(Width(4), Height(5)))
}

Обёртка для конфиденциальных данных

Класс-значение может переопределить toString, чтобы скрывать секреты в журналах, сохраняя доступ к исходному значению.

@JvmInline
value class Token(val value: String) {
    override fun toString() = "Token(***)"
}

fun main() {
    val t = Token("abc123")
    println(t)          // masked
    println(t.value)    // real value when needed
}

Проверка диапазонов

Используйте классы-значения, чтобы сосредоточить правила диапазона в одном месте и сделать невозможным создание недопустимых состояний.

@JvmInline
value class Rating(val stars: Int) {
    init {
        require(stars in 1..5) { "stars must be 1..5" }
    }
}

fun main() {
    println(Rating(4).stars)
}

Умные конструкторы

Объедините класс-значение с фабрикой-компаньоном, которая возвращает null при недопустимом вводе, чтобы не использовать исключения для ожидаемых ошибок.

@JvmInline
value class Age(val value: Int) {
    companion object {
        fun of(n: Int): Age? = if (n in 0..150) Age(n) else null
    }
}

fun main() {
    println(Age.of(30)?.value)
    println(Age.of(-5))
}

Итоги шаблонов

Распространённые варианты использования классов-значений:

  • Типизированные идентификаторы для предотвращения путаницы
  • Единицы измерения
  • Проверяемые примитивные значения с помощью init
  • Операции предметной области с помощью операторов
  • Скрытие конфиденциальных значений

Безопасность без затрат

Поскольку классы-значения обычно встраиваются, Вы получаете всю эту ясность предметной области и безопасность практически без затрат во время выполнения. Это простой способ сделать недопустимые состояния непредставимыми.

Быстрая проверка

Проверьте, насколько хорошо Вы понимаете варианты использования классов-значений.

Итоги

Вы увидели практические варианты использования классов-значений:

  • Типизированные идентификаторы, единицы измерения и проверяемые строки
  • Деньги и операции предметной области
  • Скрытие секретов и умные конструкторы

Далее: ограничения классов-значений.

Часто задаваемые вопросы

Урок «Варианты использования» бесплатный?

Да — полный текст урока «Варианты использования» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.

Чему я научусь в уроке «Варианты использования»?

Моделирование предметной области Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Kotlin Academy?

Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Варианты использования»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Kotlin Academy?

Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Псевдонимы типов
  2. Встраиваемые классы-значения
  3. Варианты использования
  4. Ограничения
← Назад к Kotlin Academy