Напоминаю, что это заметки во время чтения книги банды четырех "Паттерны объектно-ориентированного проектирования", а не мои личные выводы.
Наследование и композиция — два самых популярных инструмента против дублирования.
Наследование позволяет определить реализацию одного класса через другой. Повторное использование за счет создания подкласса еще называют повторным использованием по принципу прозрачного ящика (white box reuse). Такой термин подчеркивает, что внутреннее устройство родительских классов частично видимо подклассам. Я раньше не слышала такую формулировку. Звучит интересно.
Композиция — альтернатива наследованию. Тут новая сложная функциональность получается путем объединения или композиции объектов. Для композиции необходимо, чтобы у объектов были четко определенные интерфейсы.
У обоих есть плюсы и минусы.
Наследование:
✅ Определяется статически на этапе компиляции. По моему не очень объективному мнению, когда что-то происходит на этапе компиляции — это всегда плюс.
✅ Проще использовать. Наследование — то, что знают даже джуниоры и это прям основы основ. Повторное использование кода при наследовании упрощает создание новых методов/классов/переменных, которые можно применять со старыми.
✅ Упрощается задача модификации существующей реализации. Если что-то захотим добавить или удалить, то проблем быть не должно.
➖ Нельзя изменить во время выполнения. Вот прям быстро не смогла придумать, когда это может понадобиться, но наверняка может быть такая ситуация.
➖ Родительский класс часто частично определяет что-то для подклассов. А раз подкласс знает реализацию родительского класса, то наследование нарушает инкапсуляцию. Да, такое и правда есть. Сама замечала, что в коде такое встречается.
➖ Подкласс и класс тесно связаны, так что изменения родителя требуют изменять реализацию детей. Тут поможет наследование только от абстрактных классов.
Композиция:
✅ Определяется динамически во время выполнения, когда объекты получают ссылки на другие объекты. Да, это тоже плюс, хотя выше для наследования первый пункт был полностью противоположным и тоже плюсом.
✅ Требуется, чтобы объекты соблюдали интерфейсы друг друга.
➖Требуется тщательно проектировать интерфейсы.
✅ Инкапсуляция не нарушается, потому что доступ к объектам только через их интерфейсы.
✅ Во время выполнения любой объект можно заменить другим (главное, чтобы был такой же тип).
✅ Зависимость от реализации минимальна.
✅➖ Классы небольшие, но их много. Тут я поставила плюс-минус, но лично я считаю весь пункт как плюс.
Совет от автора: предпочитайте композицию, а не наследование. Даже если сравнить минусы, то у наследования три, а у композиции всего 1,5.
Наследование и композиция часто используются вместе.
И тут автор говорит, что архитекторы злоупотребляют наследованием и что надо больше полагаться на композицию. Я пыталась представить проект полностью на композиции без наследования и у меня не получилось. Это ведь даже банально для фрагментов нужен какой-нибудь BaseFragment и BaseViewModel. Но с другой стороны, во всех остальных случаях действительно лучше подходит композиция.
Предыдущие части: