Пример компоновки и агрегации с диаграммой классов UML
Я не могу полностью понять разницу между агрегацией и композицией в коде.
Клиент <. > ---- > BankAccount
(это должна быть диаграмма класса композиций Client-BankAccount).
Итак, в этом примере у Клиента есть банковский счет, поэтому это означает, что когда объект клиента умирает, его объект банковского счета также умирает. Означает ли это, что мы должны иметь объект BankAccount в классе Client?
Class Client
{
BankAccount acc = new BankAccount();
public void addMoneyToBankAccount(decimal amount)
{
acc.AddMoney(amount);
}
public decimal CheckBalance()
{
return acc.CheckAccountBalance();
}
}
Итак, эта композиция в коде? Как в этом примере будет выглядеть агрегация?
Извините за вопрос о новичке, пожалуйста, исправьте меня, если код был неправильным. Спасибо заранее.
Ответы
Ответ 1
Да, то, что вы делаете, это композиция звонка, если вы хотите сделать для вас агрегацию следующим образом:
Class Client
{
BankAccount acc;
public Client(BankAccount p_acc)
{
acc=p_acc;
}
public void addMoneyToBankAccount(decimal amount)
{
acc.AddMoney(amount);
}
public decimal CheckBalance()
{
return acc.CheckAccountBalance();
}
}
Агрегация
Если наследование дает нам "is-a", а композиция дает нам "часть", мы можем утверждать, что агрегация дает нам отношение "has-a". Внутри агрегации время жизни части не управляется целым. Чтобы сделать это более ясным, нам нужен пример. За последние 12 месяцев я занимался внедрением CRM-системы, поэтому я собираюсь использовать часть этого в качестве примера.
Система CRM имеет базу данных клиентов и отдельную базу данных, которая содержит все адреса в географической области. Агрегация имеет смысл в этой ситуации, так как у Клиента есть "Адрес". Не имеет смысла говорить, что Адрес является "частью" Клиента, потому что это не так. Рассматривайте это так, если клиент перестает существовать, имеет ли адрес? Я бы сказал, что он не прекращает свое существование. Агрегация показана на диаграмме UML в виде незаполненного алмаза.
Как я уже сказал в начале ответа, это мой подход к составу и агрегации. Принятие решения о том, следует ли использовать состав или агрегацию, не должно быть сложным. При моделировании объектов следует сказать, что это "часть" или "есть-а"?
Ответ 2
Ваш код client-BankAccount является отношением composition
Ваш код удовлетворяет всем свойствам композиции
- > время жизни классификатора частей (BankAccount
) зависит от времени жизни всего классификатора (Client
).
- > данные обычно протекают только в одном направлении (то есть от всего классификатора (Client
) до классификатора детали (BankAccount
).
Агрегация может быть представлена путем передачи BankAccount клиенту в качестве аргумента метода
Итак, этот код - Aggregation
class client
{
public bool updateAccount(BankAccount ba){....}
}
Как вы можете видеть, он удовлетворяет всем свойствам агрегирования
- > он может существовать независимо от Client
- > Данные передаются от всего классификатора (Client
) к части (BankAccount
)
Ответ 3
Это объяснение от IBM полезно для меня:
Например, мы можем думать о Автомобиле как целом объекте и Автомобильном Колесе как части общего Автомобиля. Колесо может быть создано за несколько недель раньше времени, и оно может сидеть на складе перед тем, как его поставить на автомобиль во время сборки. В этом примере экземпляр класса Wheel явно живет независимо от экземпляра класса Car. Тем не менее, бывают случаи, когда жизненный цикл класса детали не зависит от цикла целого класса - это называется агрегационной агрегацией. Рассмотрим, например, отношения компании с ее отделами. И Компания, и Департаменты моделируются как классы, и отдел не может существовать до того, как компания существует. Здесь экземпляр класса Департамента зависит от существования экземпляра класса компании.
Таким образом, жизненный цикл создателя/разрушителя (новый, выпуск) для композиции входит в экземпляр; агрегирование должно иметь возможность вместо addObject, и метод просто сохраняет идентификатор объекта как атрибут самого себя. Таким образом, в приведенном выше примере "Клиент и банковская учетная запись" действительно зависит от бизнеса, чтобы определить, может ли учетная запись существовать, даже если запись клиента уничтожена (потерянные учетные записи). Если это aggegator, у вас есть методы Клиента:
Class Client {
- (void) addToAccount:(BankAccount *)acc;
- (void) removeFromAccount:(BankAccount *)acc;
}
а метод закрытой учетной записи будет частью экземпляра объекта BankAccount, поскольку он может существовать независимо от Клиента.
по сравнению с методом компоновки, который требует, чтобы Клиент существовал, и если Клиент перестает существовать, все учетные записи, принадлежащие этому владельцу учетной записи, удаляются. Поэтому вы должны попросить объект Client создать свою учетную запись:
Class Client {
- (BankAccount *) openAccount;
- (BOOL) closeAccount:(BankAccount *)acc;
}
Ответ 4
Да, вы правы. Это простая композиция.
Для агрегации ваш класс Client должен хранить ссылку для класса BankAccount, но не должен контролировать его срок службы объекта.
class Client
{
private readonly BankAccount _account;
public Client(BankAccount account)
{
_account = account;
}
//...
}
После того, как объект Client будет уничтожен, объект BankAccount, используемый внутри, может быть назначен другому клиенту.