ключових висновки
1. Пишіть чистий код, який легко читати та підтримувати
Єдиний дійсний показник якості коду: WTFs/хвилина
Читабельність є найважливішою. Чистий код повинен бути легко зрозумілим для інших розробників. Він має бути простим, елегантним і без зайвих елементів. Намагайтеся писати код, який чітко виражає свій намір без потреби в обширних коментарях. Використовуйте значущі імена змінних і функцій, тримайте функції невеликими та зосередженими, організовуйте код логічно.
Підтримуваність дозволяє еволюцію. Код, який важко змінити, стає тягарем. Проектуйте свій код так, щоб він був гнучким і модульним, щоб він міг адаптуватися до змінних вимог. Дотримуйтесь принципів, таких як DRY (Don't Repeat Yourself) і SOLID, щоб створювати слабо зв'язані, високо когерентні системи. Безжально рефакторіть, щоб покращити структуру коду без зміни поведінки.
Чистий код окупається. Хоча написання чистого коду вимагає більше зусиль на початку, це економить значний час і зменшує головний біль у довгостроковій перспективі. Чистий код легше налагоджувати, розширювати та підтримувати. Він дозволяє розробникам працювати ефективніше і знижує ризик введення помилок під час змін. Зробіть чистий код основною частиною вашої практики розробки.
2. Дотримуйтесь значущих конвенцій іменування
Ім'я змінної, функції або класу повинно відповідати на всі важливі питання. Воно повинно пояснювати, чому існує, що робить і як використовується.
Використовуйте імена, що розкривають намір. Обирайте імена, які чітко передають призначення та поведінку змінних, функцій і класів. Уникайте однолітерних імен або криптичних абревіатур. Використовуйте вимовні імена, які легко шукати. Наприклад:
- Погано: d (час, що минув у днях)
- Добре: elapsedTimeInDays
Будьте послідовними та точними. Використовуйте послідовні конвенції іменування у всьому коді. Будьте точними, щоб уникнути двозначності - наприклад, використовуйте значущі відмінності, такі як getActiveAccounts() і getActiveAccountInfo(). Уникайте кодувань або префіксів, які додають шум без цінності. Імена класів повинні бути іменниками, імена методів - дієсловами.
Довжина імені повинна відповідати області. Використовуйте довші, більш описові імена для змінних і функцій з більшою областю. Короткі імена прийнятні для невеликих, локальних областей. Довжина імені повинна бути пропорційною до області його використання. Оптимізуйте для читабельності та розуміння в контексті, де використовується ім'я.
3. Тримайте функції невеликими та зосередженими
Функції повинні робити одну річ. Вони повинні робити це добре. Вони повинні робити це тільки.
Маленьке - це красиво. Функції повинні бути невеликими - зазвичай 5-10 рядків. Вони повинні вміщуватися на одному екрані і бути миттєво зрозумілими. Витягуйте код у добре названі допоміжні функції, а не пишіть довгі, складні функції. Невеликі функції легше зрозуміти, тестувати та підтримувати.
Робіть одну річ добре. Кожна функція повинна мати одну, чітку мету. Якщо функція виконує кілька речей, витягніть їх у окремі функції. Ознаки того, що функція робить занадто багато, включають:
- Кілька рівнів абстракції
- Кілька секцій або блоків коду
- Багато параметрів
Підтримуйте один рівень абстракції. Оператори в межах функції повинні бути на одному рівні абстракції. Не змішуйте високорівневу логіку з низькорівневими деталями. Витягуйте низькорівневі операції в окремі функції. Це покращує читабельність, зберігаючи функції зосередженими та концептуально простими.
4. Практикуйте правильне форматування та організацію
Форматування коду - це про комунікацію, а комунікація - це перше завдання професійного розробника.
Послідовне форматування має значення. Використовуйте послідовні відступи, розриви рядків і пробіли у всьому коді. Це покращує читабельність і знижує когнітивне навантаження. Домовтеся про стандарти форматування з вашою командою і використовуйте автоматизовані інструменти для їх дотримання. Основні рекомендації щодо форматування включають:
- Правильні відступи
- Послідовне розміщення дужок
- Логічні розриви рядків
- Відповідні пробіли
Організуйте код логічно. Групуйте пов'язаний код разом і відокремлюйте непов'язаний код. Використовуйте порожні рядки для створення "абзаців" між логічними секціями. Розміщуйте пов'язані функції поруч одна з одною. Тримайте файли зосередженими на одній концепції або компоненті. Розбивайте великі файли на менші, більш зосереджені, коли це доречно.
Дотримуйтесь стандартних конвенцій. Дотримуйтесь стандартних конвенцій для вашої мови та спільноти. Це робить ваш код більш знайомим і доступним для інших розробників. Наприклад, у Java:
- Імена класів використовують PascalCase
- Імена методів використовують camelCase
- Константи використовують ALL_CAPS
5. Управляйте залежностями та уникайте дублювання
Дублювання може бути коренем усього зла в програмному забезпеченні.
Усувайте дублювання. Дубльований код - це втрата можливості для абстракції. Коли ви бачите дублювання, витягніть загальний код у повторно використовувану функцію або клас. Це покращує підтримуваність, централізуючи логіку і знижуючи ризик несумісних змін. Типи дублювання, на які слід звертати увагу:
- Ідентичні блоки коду
- Подібні алгоритми з невеликими відмінностями
- Повторювані ланцюжки switch/case або if/else
Управляйте залежностями обережно. Мінімізуйте залежності між модулями, щоб зменшити зв'язність. Використовуйте ін'єкцію залежностей і інверсію контролю, щоб зробити код більш модульним і тестованим. Дотримуйтесь принципу інверсії залежностей - залежте від абстракцій, а не від конкретних реалізацій. Це робить ваш код більш гнучким і легким для змін.
Використовуйте принцип найменшого знання. Модуль не повинен знати про внутрішню структуру об'єктів, які він маніпулює. Це знижує зв'язність між модулями. Наприклад, використовуйте закон Деметри - метод повинен викликати методи тільки на:
- Своєму власному об'єкті
- Об'єктах, переданих як параметри
- Об'єктах, які він створює
- Своїх прямих компонентах
6. Обробляйте помилки акуратно
Обробка помилок важлива, але якщо вона затінює логіку, це неправильно.
Використовуйте виключення замість кодів помилок. Виключення є чистішими і не захаращують основну логіку вашого коду. Вони дозволяють відокремити обробку помилок від основного шляху. При використанні виключень:
- Створюйте інформативні повідомлення про помилки
- Надавайте контекст з виключеннями
- Визначайте класи виключень на основі потреб викликувача
Не повертайте null. Повернення null призводить до виключень нульових вказівників і захаращує код перевірками на null. Натомість:
- Поверніть порожні колекції замість null для списків
- Використовуйте патерн Null Object
- Використовуйте Optional у Java або Maybe у функціональних мовах
Пишіть try-catch-finally спочатку. Починайте з try-catch-finally, коли пишете код, який може викликати виключення. Це допомагає визначити область і очікування для викликувального коду. Це забезпечує правильне управління і звільнення ресурсів, навіть у випадках помилок.
7. Пишіть ретельні модульні тести
Тестовий код так само важливий, як і виробничий код.
Дотримуйтесь трьох законів TDD. Розробка через тестування (TDD) покращує якість і дизайн коду:
- Напишіть невдалий тест перед написанням будь-якого виробничого коду
- Напишіть лише стільки тесту, щоб продемонструвати невдачу
- Напишіть лише стільки виробничого коду, щоб пройти тест
Тримайте тести чистими та підтримуваними. Застосовуйте ті ж стандарти якості коду до ваших тестів, як і до виробничого коду. Регулярно рефакторіть і покращуйте тестовий код. Добре структуровані тести служать документацією і дозволяють безстрашно рефакторити виробничий код.
Спрямовуйтеся на всебічне покриття тестами. Пишіть тести, які охоплюють крайні випадки, граничні умови і сценарії помилок - не тільки основний шлях. Використовуйте інструменти покриття коду, щоб виявити прогалини в покритті тестами. Пам'ятайте, що 100% покриття не гарантує відсутність помилок, але надає впевненість у рефакторингу і змінах.
8. Постійно рефакторіть код
Залиште кемпінг чистішим, ніж ви його знайшли.
Рефакторіть опортуністично. Покращуйте структуру коду, коли працюєте над його частиною. Дотримуйтесь правила бойскаута: залиште код кращим, ніж ви його знайшли. Невеликі, поступові покращення накопичуються з часом і запобігають гниттю коду. Загальні техніки рефакторингу включають:
- Витягування методів або класів
- Перейменування для ясності
- Спрощення складних умов
- Усунення дублювання
Рефакторіть безпечно з тестами. Завжди майте надійний набір тестів перед рефакторингом. Робіть невеликі, поступові зміни і часто запускайте тести. Це дає вам впевненість, що ваші зміни не порушують існуючу функціональність. Використовуйте автоматизовані інструменти рефакторингу, коли це можливо, щоб зменшити ризик введення помилок.
Баланс між рефакторингом і наданням цінності. Хоча постійний рефакторинг важливий, не дозволяйте йому паралізувати прогрес. Спрямовуйтеся на "достатньо добре", а не на досконалість. Зосередьте зусилля рефакторингу на найбільш проблемних або часто змінюваних областях коду. Пояснюйте цінність рефакторингу зацікавленим сторонам, щоб забезпечити підтримку для постійного покращення коду.
9. Застосовуйте принципи об'єктно-орієнтованого та функціонального програмування
Об'єкти приховують свої дані за абстракціями і надають функції, які працюють з цими даними. Структури даних відкривають свої дані і не мають значущих функцій.
Використовуйте об'єктно-орієнтовані принципи розумно. Застосовуйте принципи, такі як інкапсуляція, наслідування і поліморфізм, щоб створювати гнучкі, модульні дизайни. Дотримуйтесь принципів SOLID:
- Принцип єдиної відповідальності
- Принцип відкритості/закритості
- Принцип підстановки Лісков
- Принцип сегрегації інтерфейсу
- Принцип інверсії залежностей
Використовуйте концепції функціонального програмування. Навіть у об'єктно-орієнтованих мовах техніки функціонального програмування можуть призвести до чистішого коду:
- Чисті функції без побічних ефектів
- Незмінні дані
- Функції вищого порядку
- Композиція функцій
Обирайте правильний підхід для проблеми. Об'єктно-орієнтовані та функціональні парадигми мають свої сильні та слабкі сторони. Використовуйте об'єктно-орієнтований дизайн, коли потрібно моделювати складні домени з поведінкою. Використовуйте функціональні підходи для трансформації даних і обробки потоків. Багато сучасних мов підтримують гібридний підхід, дозволяючи використовувати найкращий інструмент для кожної частини вашої системи.
10. Ретельно розглядайте паралелізм
Паралелізм - це стратегія роз'єднання. Він допомагає роз'єднати те, що робиться, від того, коли це робиться.
Розумійте виклики паралелізму. Паралельне програмування вводить складність і потенціал для тонких помилок. Загальні проблеми включають:
- Умови гонки
- Взаємні блокування
- Пропущені сигнали
- Проблеми видимості пам'яті
Відокремлюйте питання паралелізму. Тримайте ваш код, пов'язаний з паралелізмом, окремо від іншого коду. Це полегшує розуміння і тестування. Використовуйте абстракції, такі як Executors, Futures і Actors, для управління паралелізмом, а не працюйте з сирими потоками.
Віддавайте перевагу незмінності та чистим функціям. Незмінні об'єкти і чисті функції є природно потокобезпечними. Вони усувають багато проблем паралелізму, уникаючи спільного змінного стану. Коли змінний стан необхідний, використовуйте правильні техніки синхронізації і розглядайте використання атомарних змінних або конкурентних колекцій.
Останнє оновлення:
Відгуки
Чиста архітектура отримує переважно позитивні відгуки за свої принципи написання зрозумілого та підтримуваного коду. Читачі цінують практичні поради щодо найменування, функцій та тестування. Зосередженість книги на Java та деякі надто суворі рекомендації викликають поширену критику. Багато хто вважає її обов'язковою для читання розробниками, хоча деякі вважають її менш корисною для досвідчених програмістів. Дослідження випадків та приклади рефакторингу отримують похвалу від одних, але критику від інших як надмірні. Загалом, рецензенти погоджуються, що книга пропонує цінні інсайти щодо якості коду, навіть якщо не всі пропозиції є універсально застосовними.