Конспект книги «Elegant Objects»

, books · dev

Егор Бугаенко написал полезную книгу про ООП. Я её прочитал и сделал для себя короткий конспект.

Современное ООП не правильно приготовлено, оно больше похоже на процедурный стиль потому, что выросло из него. Проблема больших программных продуктов — maintainability (ремонтопригодность, поддерживаемость). Решить помогает чистый стиль ООП — очень маленькие классы, immutable объекты и прочее.

Не использовать -er в именовании классов

Manager, Controller, Formatter — плохие имена плохих классов. Класс должен отражать не то, что он делает, а то, кто он есть.

Один главный конструктор в классе

Все остальные конструкторы его вызвают. Так есть единый код создания объекта, который легче поддерживать.

Конструкторы не должны содержать выполняющий код

Конструкторы только создают/инициализируют объект, вся полезная работе происходит в методах.

Делайте классы как можно мельче

Инкаплируйте максимум 4 объекта. Такие классы легче поддерживать и тестировать.

Всегда используйте интерфейсы

Интерфейс — это задокументированный контракт, который класс будет выполнять. (Спорно)

Методы-билдеры именуйте существительными

Например: string content(File file), int sum(int, int)

Методы-манипуляторы именуйте глаголами

Например: void paint(Color color), void write(string s). Такие методы не должны что-то возвращать, всегда void.

Методы возвращающие булевый тип именуйте прилагательными

Например: bool empty(), bool negative().

Не используйте константы

Они добавляют связи между классами, а это плохо. Вместо констант нужно делать классы, которые имплементируют работу с этими константами. (Спорно)

Делайте объекты не изменяемыми (immutable)

Такие объекты лечге поддерживать и отлаживать. Есть если объект должен изменить своё внутренне состояние, значит нужно создать и вернуть новый объект с новым внутренним состоянием. Плюсы такие:

  • объект всегда остайтся самим собой, нет identity mutability,
  • failure atomicity — ошибки не влияют на внутреннее состояние объекта, он всегда остайтся собой,
  • нет сайд-эффектов,
  • нет null в полях, всё должно быть проинициализировано в конструкторе,
  • потокобезопасность — много потоков могут пользовать объект без синхронизаций,
  • маленькие и простые классы — трудно сделать immutable класс в 5000 строк.

Пишите тесты вместо документации

Плохой код вынуждает писать документацию к нему. Простые маленькие классы не нуждаются в документации. Хорошо написанные юнит тесты для класса и есть его документация.

Не используйте моки, используйте фейки.

Моки это плохо потому, что они связаны с внутренним состоянием класса. Фейковые классы живут рядом с интерфейсами, реализуют их и используются, когда нужна имплемениация интерфейса для юнит тестов.

Максимум 5 публичных методов в классе

Маленькие классы легче понимать, поддерживать и тестировать.

Не используйте статические методы

Статические методы из процедурного стиля программирования. Они удобны для компьютера, но плохи для ООП, классов, поддержки и тестирования. Императивный стиль — это про алгоритмы и исполнение. Декларативный — про объекты и поведение. Нужно стремиться к декоративному стилю.

Не используйте utility классы, хелперы

Это обычно не классы, а набор процедур. Это очень частый антипаттерн в ООП.

Не используйте синглтоны

Немного лучше, чем utility класс. Но без него можно. Не используйте их. Объект не должен трогать ничего кроме своих инкапсулированных свойств. Все остальное объекту нужно передавать в конструкторе.

Функциональное программирование

Оно конечно хорошее, но ООП более выразительное и мощное потому, что имеет не только методы (функции), но и объекты.

Не принимайте NULL-аргументов

Это избавляет от проверки на null. Null - это из мира компьютеров, а не из мира объектов.

Be loyal and immutable, or constant

Коротко не скажешь, нужно читать.

Не используйте геттеры и сеттеры

Объекты в ООП не просто структуры данных. Структура данных прозрачная, а объект — черный ящик. Структурв данных пассивная, объект — активный. Геттеры и сеттеры нарушают целостность объекта, он становится не иммутабельным.

Используйте new только во вторичных конструторах

Для создания объектов по-умолчанию.

Избегайте проверки и приведения типов

Reflection — это хороший инструмент для плохих программистов.

Никогда не возвращайте NULL

Лучше выбрасывайте исключение. Fail fast — чем раньше вы упадёте, тем быстрее вы найдёте ошибку. Вариант: возравращать объект специального класса: class NullUser implements User.

Не ловите исключения, которые вы не должны ловить

Пусть они улетают выше, fail fast.

Используйте вложенные исключения

Словили исключение, выбрасывайте новое с хорошим описанием ситуации и вложенным словленным исключением.

Одного типа исключений достаточно

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

Используйте RAII

Получение некоторого ресурса неразрывно совмещается с инициализацией, а освобождение — с уничтожением объекта.