Українська
UML і контракт класу
UML і перевірка класу
У UML прямокутник класу має назву, властивості й операції. Позначення + означає public, - – private, # – protected. Для властивості із закритим сетером додайте примітку «public get, private set». UML має відображати контракт, а не кожен локальний лічильник із тіла функції.
До запуску визначте таблицю перевірок: допустимий початковий стан, нижня межа, верхня межа, неправильне значення, успішна зміна, відмова без зміни, два незалежні об’єкти та два посилання на один об’єкт. Для Double додайте NaN і нескінченність. Виконання лише «щасливого» сценарію не перевіряє інваріант.
У IntelliJ IDEA поставте точку зупинки в init і сетері. Покроково створіть об’єкт, змініть властивість і спробуйте відмову. Порівняйте значення до та після. Для аналізу JVM-коду відкрийте Tools → Kotlin → Show Kotlin Bytecode і Decompile, якщо ці дії доступні у встановленій версії IDE. https://www.jetbrains.com/help/idea/create-your-first-kotlin-app.html.
Звичайні Kotlin-властивості на JVM зазвичай представлені полем і методами доступу для Java, наприклад getBalance(). @JvmField за певних умов відкриває поле без таких аксесорів; це інструмент сумісності, який не слід застосовувати механічно до властивостей, що мають підтримувати інваріант.
Читання контракту перед написанням коду
Почніть із речення «об’єкт зобов’язаний завжди…». Для рахунку це невід’ємний залишок; для прямокутника – додатні сторони; для треку – непорожня назва та додатна тривалість. Далі запишіть усі входи до об’єкта: конструктори, сетери, методи, а також посилання на змінні об’єкти, які повертають геттери. Кожен із цих входів може порушити правило, якщо його забути.
Відокремте інваріант від передумови окремої операції. Баланс не може бути від’ємним за жодних обставин; сума зняття має бути додатною лише для конкретного виклику withdraw. Після успішного виклику постумовою буде зменшення залишку на вказану суму. Після відмови постумовою є незмінність балансу. Таке формулювання одразу підказує очікувані результати тестів.
Таблиця 5.1. Контрактні перевірки рахунку
| Сценарій | Очікування | Що доводить |
|---|---|---|
| Баланс 1000, зняття 200 | Баланс 800 | Правильність дії |
| Баланс 1000, зняття 1000 | Баланс 0 | Допустиму межу |
| Баланс 1000, зняття 1001 | Відмова, баланс 1000 | Збереження стану |
| Зняття 0 або −1 | Відмова | Перевірку передумови |
| Створення з −1 | Об’єкт не створено | Перевірку конструктора |
Окремо подумайте про числове представлення. Long точний для цілих копійок у межах свого діапазону, але операції над ним можуть переповнюватися. Тому в Account верхня межа перевіряється через різницю до додавання. Перевірка лише вже обчисленої суми може бути запізнілою. Для довільних великих сум на JVM існують інші типи; ця тема навчає відповідальності моделі, а не побудови промислової фінансової системи.
Для дійсних значень перевіряйте скінченність та одиниці. Помилка «метри замість сантиметрів» не виправляється типом Double. Однозначно назвіть аргумент radiusMeters або запишіть одиницю в документації. Не приховуйте перетворення під неочевидним сетером, який змінює ще кілька незалежних полів. Обчислення з похибкою перевіряють із допустимим відхиленням.