DEV_EASY_NOTES Telegram 28
​​Я долго думал, чтобы такого не сложного рассказать по архитектуре и не придумал ничего умнее.
Композия или наследование?

Представим, что у нас есть такой класс 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 то композиция.
👍143



tgoop.com/dev_easy_notes/28
Create:
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

View MORE
Open in Telegram


Telegram News

Date: |

Choose quality over quantity. Remember that one high-quality post is better than five short publications of questionable value. Judge Hui described Ng as inciting others to “commit a massacre” with three posts teaching people to make “toxic chlorine gas bombs,” target police stations, police quarters and the city’s metro stations. This offence was “rather serious,” the court said. So far, more than a dozen different members have contributed to the group, posting voice notes of themselves screaming, yelling, groaning, and wailing in various pitches and rhythms. Select: Settings – Manage Channel – Administrators – Add administrator. From your list of subscribers, select the correct user. A new window will appear on the screen. Check the rights you’re willing to give to your administrator. More>>
from us


Telegram Dev Easy Notes
FROM American