Обобщение прецедентов по сравнению с расширением

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

Use case generalisation image

Use case extension image

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

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

void makePayment(const PaymentDetails* pd)
{
   pd->pay();
}

в противоположность

void makePayment(const PaymentDetails* pd)
{
   switch(pd->type)
   {
       case EFT:
                payViaEFT(pd); 
                break;
       case PAYPAL:
                payViaPayPal(pd); 
                break;
       case CREDITCARD:
                payViaCreditCard(pd); 
                break;
   }
}

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

3 ответов


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

Это верно.

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

в схеме не диктуйте никакой реализации. Однако вы можете интерпретировать подсказку из диаграммы для себя. UML остается независимым от языка и решения.

не является ли этап прецедента слишком ранним для такой реализации конкретные проблемы для моделирования?

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

есть гораздо более подходящие UML схемы для этого.

вы действительно можете использовать их параллельно :) поскольку они разные взгляды на одну и ту же тему.

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

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


при моделировании с отношением расширения расширяющийся вариант использования (оплата через xxx) выполняется, когда расширенный вариант использования (оплата) находится в точном месте (заданном точкой расширения, типом оплаты), если условие для такого отношения расширения выполняется (например, для "оплата через Paypal", условием будет payment_type=PAYPAL). В этой модели "оплатить через Paypal "касается только деталей завершения платежной операции с Paypal, в то время как "произвести оплату" указывает все поведение, не зависящее от способа оплаты (например, вычисление общей суммы и сохранение результата транзакции после ее выполнения).

расширение варианта использования не означает, что альтернативы должны быть жестко закодированы. Действительно, ваш первый пример также является допустимой реализацией отношения extend, так как pd->pay(pd) будет вызывать различное поведение в зависимости от выбранного типа оплаты. На самом деле, используйте case diagram models что должна делать система, в то время как низкий уровень детали реализации лучше указывать на диаграммах деятельности.


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

вы можете посмотреть на отношение" is a", чтобы определить, какой из них использовать. Pay by PayPal "является" сделать платеж, конкретный способ сделать платеж. Введите код скидки нет. Это что-то дополнительное, что вы можете сделать во время оплаты.