Разграничение между делегацией, составом и агрегацией (java OO design)

Я столкнулся с постоянной проблемой, отличающей делегирование, состав и агрегацию друг от друга, и выявление случаев, когда их лучше всего использовать один над другим.

Я консультировался с java OO аналитическим и дизайнерским книгой, но моя путаница все еще остается. Главное объяснение:

делегирование. Когда мой объект использует другую функциональность объекта, не меняя ее.

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

агрегация. Мой объект состоит из других объектов, которые могут жить даже после уничтожения моего объекта.

Возможно ли иметь несколько простых примеров, демонстрирующих каждый случай, и рассуждения позади них? Как еще можно продемонстрировать эти примеры, кроме моего объекта, просто имея ссылку на другой объект (ы)?

47
задан 06 сент. '09 в 1:39
источник поделиться
4 ответов

Ваш объект будет ссылаться на другой объект во всех трех случаях. Разница заключается в поведении и/или жизненном цикле ссылочных объектов. Некоторые примеры:

  • Состав: Дом содержит одну или несколько комнат. Продолжительность жизни дома контролируется Хаусом, поскольку Комната не будет существовать без Дома.

  • Агрегация: дом для игрушек, построенный из блоков. Вы можете разобрать его, но блоки будут оставаться.

  • Делегация: Ваш босс попросил вас дать ему кофе, вместо этого вы сделали стажер для вас. Делегирование - это не тип ассоциации (например, состав/агрегация). Последние два обсуждались в разделе "Переполнение стека" много раз

В комментарии вы спрашиваете, как реализация будет различаться в каждом случае, наблюдая, что во всех случаях мы вызываем методы для выпущенных объектов. Это правда, что в каждом случае у нас был бы код типа

myRoom.doWork();

myBlock.doWork();

myMinion.doWork();

но различия заключаются в жизненном цикле и мощности связанных объектов.

Для Компонента комнаты появляются, когда Дом создан. Поэтому мы могли бы создать их в конструкторе Дома.

В случае Ассоциации (я буду использовать Tire и Car) автомобили могут добавить Tyres в свой конструктор, но позже вы можете захотеть удалить и сменить шины. Таким образом, у вас также есть такие методы, как

 removeTyre(FrontLeft)
 addNewTyre(aTyre, BackRight)

И вполне вероятно, что объект aTyre пришел из Factory - мы не new его в любом из методов Car.

В случае делегирования вы можете даже не иметь переменную-член для хранения делегата

 resourcingPool().getIntern().getCoffee(SkinnyLatte, workstation 7);

связь между объектами продолжается только до тех пор, пока стажер выбирает кофе. Затем он возвращается в пул ресурсов.

47
ответ дан 06 сент. '09 в 2:09
источник

Делегирование

public class A {
  private B b = new B();

  public void methodA() {
    b.methodB();
  }
}

Когда клиенты A call methodA, класс A делегирует вызов B methodB.

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

Гибридное делегирование

public class A {
  private B b = new B();

  public void methodA() {
    b.methodB( this );
  }
}

Разница между делегированием, которая включает в себя простое переадресацию и делегирование, которая действует как замена для наследования, заключается в том, что вызывающий должен принять параметр вызывающего абонента, например:

    b.methodB( this );

Обоснование. Позволяет экземплярам класса B использовать функциональные возможности, доступные из класса A, так же, как класс B, если он унаследован от класса A, но без наследования. Дальнейшее изучение.

Состав

public class A {
  private B b = new B();

  public A() {
  }
}

Как только больше ссылок на конкретный экземпляр класса A не существует, его экземпляр класса B уничтожается.

Обоснование. Позволяет классам определять поведение и атрибуты модульным способом. Дальнейшее изучение.

Агрегация

public class A {
  private B b;

  public A( B b ) {
    this.b = b;
  }
}

public class C {
  private B b = new B();

  public C() {
    A a = new A( this.b );
  }
}

Как только больше ссылок на конкретный экземпляр класса A, его экземпляр класса B не будет уничтожен. В этом примере как A, так и C должны быть собраны мусор до того, как B будет уничтожен.

Обоснование. Позволяет экземплярам повторно использовать объекты. Дальнейшее изучение.

Демонстрация без ссылок

Имена, заданные этим простым шаблонам, определяются их ссылочными отношениями.

45
ответ дан 06 сент. '09 в 3:11
источник

В вашей книге объясняется неплохо, поэтому позвольте мне подробно остановиться на нескольких примерах.

делегирование: Когда мой объект использует другую функциональность объекта, а не меняет ее.

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


class FeatureHolder {
 void feature() {
  // Big implementation of the feature that you dont want to put in the class Big
 }
}

class Big {
 private FeatureHolder FH = new FeatureHolder();

 void feature() {
  // Delegate to FeatureHolder.
  FH.feature();
 }

 //.. Other features
}

Из приведенного выше примера функция Big.feature() вызова FH как не меняет ее. Таким образом, класс Big не должен содержать реализацию функции (разделение труда). Кроме того, функция() может реализовать по-разному другой класс, например "NewFeatureHolder", а Big может выбрать вместо этого новый держатель.

Состав: Мой объект состоит из других объектов, которые, в свою очередь, не могут существовать после уничтожения моего объекта - сбор мусора.

aggregation: Мой объект состоит из других объектов, которые могут жить даже после уничтожения моего объекта.

Технически композиция является "частью", а "Агрегация" относится к "отношениям". Ваши руки - часть вас. Если вы больше не будете жить, ваша рука тоже умрет. Ваша тряпка не является частью вас, но вы имеете их; как вы можете гость, ваша ткань не идет с вами.

В программировании некоторые объекты являются частью другого объекта, и без него они не имеют логического смысла. Например, кнопка состоит из оконного фрейма. Если рамка закрыта, кнопка не имеет причины больше находиться (состав). Кнопка может иметь ссылку на базу данных (например, для обновления данных); когда кнопка будет удалена, база данных все еще может находиться вокруг (Агрегация).

Извините за мой английский, надеюсь, что это поможет

14
ответ дан 06 сент. '09 в 2:44
источник

1) Делегирование: пример "водитель-водитель". Человек купил машину. Но этот человек не знает, чтобы водить машину. Поэтому он назначит водителя, который знает, как управлять автомобилем. Таким образом, класс Man хочет выполнить транспорт, используя автомобиль. Но у него нет взаимодействующей функциональности/совместимости с автомобилем. Поэтому он использует класс, который совместим с автомобилем, который является драйвером, который совместим с классом человека. Предполагая, что водитель может понять, что говорит человек

2) Состав: Моделирование автомобилей является обычным примером. Для перемещения автомобиля колесо вращается. Класс автомобиля, использующий класс колеса, вращает функциональность как часть его функции перемещения, когда колесо является частью автомобиля.

3) Агрегация: автомобиль и его цвет. Объект класса ferrari класса будет иметь объект класса цвета красный. Но объект класса цвета красного может быть как отдельный класс, когда поиск пользователя происходит со спецификацией красного цвета.

0
ответ дан 24 дек. '13 в 16:16
источник

Другие вопросы по меткам или Задайте вопрос