tgoop.com/dev_easy_notes/28
Create:
Last Update:
Last Update:
Я долго думал, чтобы такого не сложного рассказать по архитектуре и не придумал ничего умнее.
Композия или наследование?
Представим, что у нас есть такой класс Developer:
Developer{
fun writeCode()
fun drinkCoffee()
}
И мы хотим сделать класс Devops, который умеет запускать докер и помимо этого, чтобы он еще и умел пить кофе как Developer. Очевидный путь это создать класс Devops написать функцию по запуску докера, а функцию пить кофе просто скопировать из Developer.
Однако получится дублирование кода, что довольно скверно и несет кучу проблем в будущем. Как решить это дерьмо? Есть два варианта: Наследованиe и Композиция, разберем каждый.
👨👩👧 Наследованиe. Если класс
Devops
наследует класс Developer
, значит все открыте методы и поля Developer окажутся в объекте Devops
:class Devops : Developer{
fun launchDocker()
}
val devops = Devops()
devops.writeCode()
devops.launchDocker()
Вроде бы все круто, но возникает сложность. Допустим мы не хотим, чтобы Devops умел писал код (ведь
Devops
это не человек а идеалогия, но кофе пить можно!). В таком случае лучше использовать композицию.🪆Композиция, это когда одно из полей класса
Devops
является классом Developer
. Эначит мы сначала конструируем объект Developer
, а потом устанавливаем этот объект в поле объекта Devops
. А Devops
уже будет обращаться к методам из класса Developer
:class Devops(
private val developer:Developer
){
fun launchDocker()
fun drinkCoffee(){
developer.drinkCoffee()
}
}
val devops = Devops()
devops.drinkCoffee()
devops.launchDocker()
мы избавились от дублирования кода и при этом в классе
Devops
нет метода drinkCoffee()
.Возникает вопрос зачем нам тогда нужно наследование, ведь все вокруг трубят, что лучше использовать композицию а не наследование?
Самым правильным ответом на этот вопрос будет: это зависит от вашего случая.
Наследование стоит выбирать тогда, когда у двух классов есть отношение
является
. Например есть класс Promotion (Акция) и есть класс NewYearPromotion (Новогодняя акция) очевидно, что у них есть отношение является
, так как NewYearPromotion это просто другая разновидность Promotion и тут нужно наследование.Композицию стоит выбирать когда есть отношение
использует
. Допустим есть класс Car и класс Wheel, явно Car использует
Wheel, а не является Wheel значит тут нужна композиция.Некоторые практических советов как выбрать и итоги:
👉При использовании стороних библиотек, стоит унаследоваться только от абстрактных классов или интерфейсов. Во всех других случаях лучше использовать композицию. Это связано с тем, что простые классы могуть меняться, и эти изменения могут сильно стрельнуть.
👉Если вы сами делаете либу, то делайте ваши классы закрытыми для наследования. Давайте возможность клиентам наследоваться только от ваших абстактных классов и интерфейсов.
👉Если класс
B
расширяет и является классом A
то наследование.👉Если класс
B
только использует часть функционала класса A
то композиция.BY Dev Easy Notes

Share with your friend now:
tgoop.com/dev_easy_notes/28