Конспект книги «Elegant Objects»
13 Sep 2016, 15:01, 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
Получение некоторого ресурса неразрывно совмещается с инициализацией, а освобождение — с уничтожением объекта.