Обобщение случая использования и расширение

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

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. Есть ли жесткое и быстрое правило относительно того, какой из двух использовать, и если да, то что это?

Ответ 1

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

Это верно.

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

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

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

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

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

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

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

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

Ответ 2

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

С другой стороны, обобщение (которое определяется не только для использования, но и для любого классификатора) является более широким понятием, поскольку оно не детализирует (на уровне диаграммы) детали того, когда и как специализированное поведение выполняются. Если "Pay by Paypal" была специализацией "Сделать платеж", это изменило бы поведение "Make Payment", которое могло бы существенно отличаться от поведения "Pay via credit card".

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

Ответ 3

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

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