Состав против делегирования
Есть ли какая-то разница в плане реализации, как дизайн композиции может отличаться от делегирования. Например, код, который, кажется, выполняет делегирование, поскольку пользователь не может получить доступ к скомпонованному объекту (например, "a" ) без использования b. Следовательно, пользователю нужно будет вызывать интерфейсы класса b, а затем "класс b" вызывать соответствующие интерфейсы класса "a", что делает его делегированием. Это имеет смысл?
Class A {
friend class B;
private:
A(){}; //dont want user to instantiate this class object since it wont sense without any context. Just like a room with no house.
void PrintStructure(){};
};
Class B{
public:
void PrintStructure(){a.PrintStructure();} //delegate
private:
A a; //composition
};
Ответы
Ответ 1
Термин "композиция" обычно используется в терминах моделирования объектов как выражение отношения "has-a" и является формой ассоциации (другой является агрегацией). Обычно это контрастирует с отношением "наследование" ( "is-a" ). Итак:
Какая разница между композицией и агрегацией? Композиция подразумевает, что ребенок не может существовать без контекста родителя.
Например, в Доме есть один или несколько комнат. Это композиционное отношение. Удалите дом, и комнаты также перестают существовать. В Доме также есть несколько человек, являющихся экземплярами Человека. Это отношение агрегации, потому что эти люди существуют вне контекста этого дома.
Делегирование - это не что иное, как деталь реализации. Класс имеет открытый интерфейс, который описывает его состояние и поведение. Как это реализовано, не имеет значения. Он может делегировать другие объекты или нет.
Вы заметите, что оба A и B из вашего примера имеют один и тот же внешний интерфейс. Это более распространено, чтобы сделать что-то вроде этого:
// this represents an interface
class A {
public:
virtual void printStructure() = 0;
}
с конкретными классами:
class ConcreteA : A {
public:
virtual void printStructure() { ... }
}
и
class DelegateA : A {
public:
DelegateA(A& a) { this.a = a; }
virtual void printStructure() { a.printStructure(); }
private:
A a;
}
Извините, вероятно, синтаксические ошибки С++. Я немного ржавый.
Ответ 2
Есть несколько различий, которые я вижу:
- Делегирование включает методы реэкспорта; в композиционном соотношении методы внутренних объектов могут использоваться только конфиденциально и не подвергаться повторному экспонированию.
- Композиция обычно подразумевает какую-то семантику владения с последствиями для жизненного цикла объекта; родительский объект "владеет" ребенком, и у ребенка нет достаточных оснований для существования самостоятельно. Делегирование не имеет такого значения.
В коде, который вы показываете, используется делегирование и объединение; ассоциация может быть составной, но ее трудно рассказать без более широкого контекста или дополнительной информации об объектах (она может быть довольно тонкой и субъективной, когда ассоциация становится композицией).
Ответ 3
Композиция о взаимосвязях между объектами.
Делегирование - это передача работы с одного объекта на другой.
На самом деле это разные (но иногда связанные) проблемы.
У вас есть B, состоящий из A (B относится к A). B также делегирует свой один метод A.
Но так как B использование A является приватным (полностью инкапсулировано внутри черного ящика B), я бы не назвал B использованием "композиции". Я бы использовал "композицию" только в том случае, если к классу А можно было получить доступ из B. Что важно здесь, если логическая модель B "имеет-a" A.
В вашем случае B реализуется в терминах A. Так как это проблема реализации, это можно считать не частью логической модели B. То есть вы можете говорить разумно о B, не разговаривая или не заботясь о A.
Что все сказано, этот материал действительно важен только для инструментов моделирования PHB и UML. Или, возможно, если вы изучаете образцы дизайна. Я бы не стал слишком зависеть от него.
[PHB = > Pointy Haired Boss]