LINUX.ORG.RU

правильная композиция вместо наследования

 


0

2

допустим в вопросе наследование vs композиция была выбрана композиция. нужно ли дублировать интерфейс агрегируемого класса в аггрегирущем или просто сделать селектор + модификатор для инстанса аггрегируемого класса?

★★★★★

Последнее исправление: x0r (всего исправлений: 1)

Первый вариант называется «делегирование».

Ты при дизайне опирайся не на класс, а на его использование. Если тебе нужен в коде какой-то метод вложенного объекта - выноси в интерфейс родителя. Если нужно его хранить и передавать пачкой (как QFont в QPainter) - передавай целиком. Кроме тебя, никто не знает, как лучше в твоём случае.

schizoid ★★★
()
Ответ на: комментарий от anonymous

Не согласен. Звучит как наркоманский сленг.

Геморрой - это заставить безглючно работать результат их структурных фантазий.

anonymous
()

Где надо делать наследование — надо делать наследование. Где надо делать композицию - надо делать композицию (или прайват инхиританс если он есть). Зачем делать композицию вместо наследования?

nokachi
()
Ответ на: комментарий от nokachi

Во многих языках нет множественного наследования. Так что иногда там композицию приходится «выбирать»...

Хотя по большому счету, можно вообще отказаться от наследования реализаций. Только интерфейсы и композиция. Было бы еще неплохо иметь механизм делегирования реализации интерфейса одному из полей(с возможностью частичного переопределения). Тогда и кода было бы немного...

anonymous
()
Ответ на: комментарий от anonymous

Хотя по большому счету, можно вообще отказаться от наследования реализаций. Только интерфейсы и композиция.

ты предлагаешь ради изменения одного метода ваять целую обёртку?

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Я так понимаю идет речь не об изменении поведения класса (что есть очень сомнительное предприятие), а о просто использовании. То есть если хочешь заюзать функцинальность какого-то класса - просто дерни нужные методы. Наследоваться - это уже по хардкору, легко сломать класс.

dizza ★★★★★
()
Ответ на: комментарий от dizza

Теперь я не понял твой коментарий.

если хочешь заюзать функцинальность какого-то класса - просто дерни нужные методы

а как ещё бывает?

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Отнаследоваться. Раньше часто можно было услышать возгласы, что ООП рулит, потому что позволяет легко делать code reuse путем наследования. Казалось круто, что если у тебя есть SomeSuperBaseService, а ты наследуешь MyCustomSuperService.

dizza ★★★★★
()
Ответ на: комментарий от true_admin

Ну есть у тебя какой-нибудь утильный класс вроде XmlDocumentWriter. Тебе нужно сохранить, скажем отчет. И ты наследуешь от него XmlReportWriter.

dizza ★★★★★
()

зачем вообще публиковать агрегированый???

и зачем полностью дублировать ???

достаточно повторить интерфейс той чати который нужен в агрегаторе(который использует для реализации агрегируемое)

qulinxao ★★☆
()
Ответ на: комментарий от dizza

code reuse путем наследования

Наследование - это не средство повторного использования кода. Это надо написать на лбу у каждого из этих возгашающих.

annulen ★★★★★
()

дублировать интерфейс агрегируемого класса в аггрегирущем

Как уже верно отметили, сие есть делегирование. Основная фишка в том, что можно выбирать агрегированный класс в рантайме, не меняя при этом интерфейс доступа к нему.

делать селектор + модификатор для инстанса аггрегируемого класса

Тут есть тонкий момент - нельзя хранить/отдавать агрегированный объект наружу по указателю т.к.

  1. Пользователь получает указатель на агрегированный класс, сохраняя его в переменной.
  2. Объект заменяет агрегированный класс на другой.
  3. Пользователь пытается работать с сохраненным ранее указателем.
  4. FAIL!
no-such-file ★★★★★
()

допустим в вопросе наследование vs композиция была выбрана композиция

Вообще, судя по вопросу, вам, наверное, нужно было выбрать наследование. Если, конечно, базовый класс позволяет.

no-such-file ★★★★★
()
Ответ на: комментарий от annulen

Да ты что, большинство реализаций языков заставляют повторно использовать Object. Ибо как раз в нем реализовано много всего.

Если же мы говорим о том, что наследование - это неповторное использование, то можно и нужно вообще отказаться от наследования реализации(которое и есть повторное использование), оставить лишь наследование интерфейсов, как выше писали уже.

anonymous
()
Ответ на: комментарий от anonymous

нужно вообще отказаться от наследования реализации

Зачем крайности? Есть хорошие правила, а есть исключения. Технология должна быть гибкой, что бы редкие случаи тоже можно было реализовать.

Насчет Object - вполне нормальный пример исключения из правила, хотя особой проблемы не вижу, что бы его сделать интерфейсом. Может было бы лучше даже, в яве не было бы проблем с коллекциями из-за забытого переопределения equals/hashCode

dizza ★★★★★
()
Ответ на: комментарий от dizza

Так весь смысл Object'а в его реализации и заключен в большинстве языков, где он есть.

На мой взгляд, Object не нужен вообще. Хотя типы top и bottom(по Пирсу) вполне могут присутствовать в системе типов. Но с т.з. ООП это должны быть интерфейсы/абстрактные классы...

А на счет крайностей... Запрет множественного наследования - уже крайность. А по этому пути пошли уже многие языки. Тогда проще уж просто сделать удобные механизмы для делегирования реализации некоторого интерфейса некоторому полю. Единообразно, по крайней мере. Интерфейсы наследуем, без глупых ограничений. Структура объекта же строится исключительно композицией.

anonymous
()
Ответ на: комментарий от anonymous

Т.е. что-то вроде такого?

Вместо

class A {
...
}

class B extends A {
...
}
Мы должны будем писать:
interface IA {
    ...
}

class A implements IA {
    ...
}

interface IB extends IA {
    ...
}

class B implements IB {
    public this.parent implements IA {
        // возможное переопределение
        // части интерфейса IA
    }
    private A parent;
}

Хм. Несколько громоздко... Хотя если немного изменить стиль проектирование и больше юзать интерфейсы, то может и ничего так... Но обезьянкам будет неприятно.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.