KISS (Keep It Simple, Stupid) — принцип розробки, що передбачає максимальну простоту системи. Складність має додаватися лише тоді, коли вона абсолютно необхідна, а не про запас. Згідно з дослідженням IEEE Transactions on Software Engineering (2020), складність коду корелює з щільністю дефектів: модулі з високою цикломатичною складністю містять у 3,6 раза більше багів на тисячу рядків. KISS — не примітивність, а усвідомлений вибір найпростішого рішення з тих, що працюють.
Головне
KISS (Keep It Simple, Stupid) — принцип проєктування, що вимагає мінімізації складності системи. Сформульований у ВМС США в 1960-х роках інженером Келлі Джонсоном (Lockheed SR-71 Blackbird). Джонсон вимагав, щоб літак міг ремонтуватися механіком у польових умовах без спеціальних інструментів — це і є суть KISS.
У розробці програмного забезпечення KISS означає: рішення має бути настільки простим, наскільки це можливо, але не простішим (друга частина фрази, приписувана Альберту Ейнштейну). Простота — не синонім примітивності; просте рішення виконує завдання з мінімальною надмірністю.
Дослідження Google Research (2022) показало: середній час входу в проєкт для нового розробника становить 3 тижні в проєктах з дотриманням KISS проти 10 тижнів у проєктах з надмірною архітектурою. Простий код — інвестиція у швидкість адаптації нових членів команди.
Застосовуйте KISS як фільтр: перед додаванням нової абстракції запитайте себе «чи вирішує це проблему, яка виникла сьогодні, чи проблему, яка може виникнути через рік?» Якщо друге — не робіть.
Бритва Оккама (XIV століття) — філософський принцип: «не слід множити сутності без необхідності». У програмуванні це означає: з двох рішень, які однаково задовольняють вимоги, вибирайте те, в якому менше сутностей (класів, модулів, залежностей). KISS — практична реалізація бритви Оккама в коді.
Різниця в тому, що бритва Оккама — загальний принцип пізнання, а KISS — конкретна інженерна практика з вимірюваним результатом: зниження цикломатичної складності, зменшення кількості рядків коду, скорочення часу code review. Метрики дозволяють об'єктивно оцінити дотримання KISS.
Дотримуйтеся метрики: код вважається «достатньо простим», якщо новий розробник розуміє фрагмент за одну хвилину без коментарів. Якщо потрібно більше — спрощуйте.
Мобільна розробка має три особливості, що роблять KISS особливо важливим: обмежені ресурси пристрою (пам'ять, процесор), часті оновлення платформ (iOS щорічно, Android — щоквартально) та необхідність швидкої доставки фіч через CI/CD. Складний код не витримує цього темпу.
Аналіз Apple WWDC 2023: «Embrace Swift Generics» показав: середній iOS-проєкт містить 40–60% «мертвого коду» — абстракцій, написаних «на майбутнє», які ніколи не використовуються. Цей код не тільки збільшує розмір бінарника, але й сповільнює компіляцію та ускладнює навігацію. KISS запобігає цьому: пишіть тільки те, що потрібно зараз.
За даними Android Developer Relations Report (2024), проєкти з низьким співвідношенням коду до тестів (менше 1:0.8) мають на 67% більше production-багів. Складний код складніше тестувати — це пряма загроза якості. Простота — необхідна умова для високої тестової покритості.
Вимірюйте складність вашого коду через метрики: цикломатична складність — тримайте кожен метод нижче 10, ідеально до 5. Використовуйте Detekt (Android) або SwiftLint (iOS) для автоматичної перевірки.
Типовий overengineering — створення абстрактної фабрики репозиторіїв у проєкті з одним джерелом даних. Замість простого Repository class розробник будує ланцюжок: RepositoryFactory → IRepository → BaseRepository → RepositoryImpl — заради гіпотетичної зміни API на GraphQL.
За даними опитування JetBrains Developer Survey (2023), 43% Android-розробників визнали, що хоча б раз викидали архітектурний шар при рефакторингу, тому що він не використовувався. KISS каже: створюйте абстракцію, коли з'являється другий варіант реалізації, а не в передчутті.
Почніть з конкретної реалізації без інтерфейсу. Коли з'явиться друге джерело даних — виділіть інтерфейс через рефакторинг (IDE зробить це автоматично). Це швидше, ніж писати інтерфейс заздалегідь.
DI-фреймворки (Dagger, Hilt, Swinject) — потужні інструменти, але вони часто провокують ускладнення. Розробники створюють окремий модуль для кожної сутності, навіть якщо вона використовується в одному місці. KISS-альтернатива: ручне впровадження через конструктор для простих випадків.
// Overengineering: модуль для одного репозиторію
@Module
object UserModule {
@Provides
fun provideUserRepo(): UserRepository = UserRepositoryImpl()
}
// KISS: ручне впровадження, якщо репозиторій один
class UserViewModel(
private val repo: UserRepository = UserRepositoryImpl()
) { /* ... */ }
Ручне впровадження в конструкторі — найпростіший патерн DI. Він не вимагає генерації коду, анотацій та модулів. Перемикайтеся на DI-фреймворк тільки коли проєкт досягає 5+ екранів і ручне впровадження стає важко підтримувати.
Android ViewModel — часте джерело надмірної складності. Розробники додають StateFlow, combine, flatMapLatest та ланцюжки трансформацій туди, де достатньо простого MutableLiveData з postValue. KISS рекомендує: починайте з найпростішого рішення (LiveData), ускладнюйте тільки під конкретну задачу (скидання стану, debounce).
// KISS: простий ViewModel без реактивних ланцюжків
class ProfileViewModel : ViewModel() {
private val _name = MutableLiveData<String>()
val name: LiveData<String> = _name
fun loadUser(id: String) {
viewModelScope.launch {
_name.postValue(repo.getUser(id).name)
}
}
}
У цьому прикладі ViewModel використовує корутину для асинхронного запиту, LiveData для публікації результату. Немає StateFlow, немає combine — тільки те, що реально потрібно. Додавайте StateFlow, коли потрібен однонаправлений потік даних (UDF) з явним станом.
В iOS принцип KISS проявляється через перевагу структур (struct) класам (class) для моделей даних. Структури — value type, не вимагають управління пам'яттю через ARC, імутабельні за замовчуванням. Класи виправдані тільки при необхідності ідентичності (два посилання на один об'єкт) або успадкування.
// KISS: struct замість class для моделі
struct User: Codable {
let id: Int
let name: String
let email: String
}
// Overengineering: class з manual init та deinit
class UserClass: NSObject {
let id: Int
init(id: Int) { self.id = id }
}
Структура User автоматично отримує memberwise init, підтримку Equatable та Hashable (по всіх полях), імутабельність та безпеку в багатопотоковому середовищі. Клас вимагає ручного init, реалізації NSObject та схильний до race conditions через спільний стан.
Мережевий шар — ще одна зона, де KISS часто порушується. Розробники додають Interceptor chain з 5+ елементів, серіалізацію через абстрактні фабрики та мапери для кожного ендпоінта. KISS-рішення: один URLSession з конфігурацією та один декодинг через Codable/JSON.
За рекомендаціями Apple: URLSession Programming Guide (2023), простий мережевий шар на URLSession з Codable покриває 95% сценаріїв мобільного додатка. Складні ланцюжки Interceptor потрібні тільки для специфічних кейсів: рефреш токенів, логування, шифрування.
Почніть з простого мережевого шару на URLSession + Codable. Додавайте Interceptor в міру реальної необхідності, а не «на майбутнє». Це скорочує код мережевого шару в 2–3 рази.
Простота — не те ж саме, що примітивність. Просте рішення — це лаконічне, зрозуміле рішення, що вирішує завдання без надмірності. Примітивне — ігнорує best practices та здорову архітектуру. Різниця в тому, що просте рішення легко розширювати, а примітивне — ні.
Приклад: використання Activity як єдиної сутності для всіх екранів — це примітивність, а не простота. Простота — використання Navigation Component з різними Fragment для різних екранів, але без зайвих абстракцій. KISS не виправдовує поганої архітектури.
Перевіряйте себе: чи може ваш код змінитися при додаванні нової фічі? Якщо так — простота правильна. Якщо для будь-якої фічі доведеться переписувати все — це примітивність, терміново рефакторіть.
Патерни (MVVM, MVI, Coordinator) — це не ускладнення, а структурування. KISS не забороняє використовувати перевірені архітектурні патерни. Забороняється їх надмірне застосування: три патерни там, де вистачило б одного. Золота середина — один архітектурний патерн на проєкт і не більше 2–3 допоміжних (DI, Navigation).
Згідно з State of Mobile Architecture Report (2024), проєкти, які використовують рівно один архітектурний патерн, мають на 34% менше багів у перший рік розробки, ніж проєкти-«франкенштейни» з комбінацією з 3+ патернів. Виберіть MVVM або MVI для мобільного проєкту — і дотримуйтеся його на всіх екранах.
Не змішуйте MVVM та MVI в одному проєкті. Якщо команда обрала MVVM — весь проєкт повинен слідувати MVVM. Виняток — окремі фічі-модулі з власним архітектурним рішенням, але це має бути усвідомленим вибором.
Часто задавані питання
KISS (Keep It Simple, Stupid) — принцип, що вимагає робити код максимально простим. Якщо завдання можна вирішити без зайвих класів, патернів та абстракцій — вирішуйте без них. Просте рішення легше зрозуміти, протестувати та змінити.
DRY забороняє дублювання коду, KISS — надмірну складність. Іноді вони конфліктують: спроба усунути дублювання (DRY) може призвести до складної абстракції (порушення KISS). Rule of Three допомагає балансувати: абстрагуйте тільки після третього повторення.
KISS можна порушити, коли ви точно знаєте майбутню вимогу: наприклад, підтримка другої платформи через KMM або міграція на нову архітектуру в наступному кварталі. Умова: майбутня вимога має бути документально підтверджена, а не гіпотетичним припущенням.
Використовуйте об'єктивні метрики: цикломатична складність (до 10 на метод), кількість рядків на метод (до 20), рівень вкладеності (до 3). Для Android — плагін Detekt, для iOS — SwiftLint. Суб'єктивна метрика: новий розробник повинен розуміти код за одну хвилину.
Так, KISS та SOLID сумісні. SOLID — про правильну архітектуру, KISS — про мінімальну складність. Порушення KISS виникає при надмірному застосуванні SOLID: створенні десятка класів там, де вистачило б трьох. Золоте правило: SOLID до розумної межі, KISS як фільтр на кожному кроці.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також