24

UML 用例图允许两种看似等效的方式来显示给定的用例可能以几种不同的方式实现,即用例泛化而不是用例扩展。我已经看到以下基本示例使用相同频率的任何一种方法建模,有时在单个源中。

用例概括图像

用例扩展图片

在我看来,扩展是比泛化更弱的关系,因为在泛化中必须可以直接替换基本用例的专用用例,但不一定在扩展中。

在我看来,泛化意味着需要多态实现,而扩展意味着要使用一些分支结构。

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 图。关于使用两者中的哪一个,是否有硬性规定?如果是,那是什么?

4

3 回答 3

16

在我看来,扩展是比泛化更弱的关系,因为在泛化中必须可以直接替换基本用例的专用用例,但不一定在扩展中。

那是真实的。

在我看来,泛化意味着需要多态实现,而扩展意味着要使用一些分支结构。

该图没有规定任何实现。不过,您可以自己解释图表中的提示。UML 仍然独立于那里的语言和解决方案。

用例阶段是否还为时过早,无法对这种实现特定的关注点进行建模?

好吧,如上所述,UML 不强制执行任何特定类型的实现。但是,您在这里收集了一些重要的功能需求,这些需求可能会极大地影响您的时间安排和工作量。(“用信用卡付款”比“通过银行转账预付款”处理起来要复杂得多)。因此,您将努力捕捉这一点,但仍对不同的解决方案持开放态度。

有更合适的 UML 图。

您可以真正并行使用它们:),因为它们是对同一主题的不同观点。

关于使用两者中的哪一个,是否有硬性规定?如果是,那是什么?

在这种情况下,我更喜欢概括,因为实际上扩展错误地暗示可能有一种付款方式,而无需使用三个命名选项中的任何一个。正如你自己指出的那样。

于 2013-02-28T12:43:02.963 回答
10

使用扩展关系建模时,如果扩展用例(付款)位于精确位置(由扩展点、付款类型给出),则执行扩展用例(通过 xxx 付款),如果这种扩展关系的条件成立(例如,对于“通过 Paypal 付款”,条件是 payment_type=PAYPAL)。在该模型中,“Pay via Paypal”只处理通过Paypal完成支付交易的细节,而“Make Payment”则指定了所有与支付方式无关的行为(如计算总金额、保存交易执行后的结果)。

另一方面,泛化(不仅为用例定义,还为任何分类器定义)是一个更广泛的概念,因为它没有详细说明(在图表级别)何时以及如何执行专门行为的细节。如果“通过 Paypal 付款”是“付款”的一种特殊形式,它将重新定义“付款”的行为,这可能与“通过信用卡付款”的行为大不相同。

作为一个扩展用例并不意味着必须对替代方案进行硬编码。实际上,您的第一个示例也是扩展关系的有效实现,因为pd->pay(pd)将根据所选支付类型调用不同的行为。实际上,用例图对系统应该做什么进行建模,而在活动图中更好地指定低级实现细节。

于 2013-02-28T14:59:20.447 回答
6

扩展的一个示例是“输入折扣码”用例。输入折扣代码与付款有关,但您无需输入折扣代码即可付款。

您可以查看“是”关系来确定使用哪个。Pay by PayPal“是一种”付款方式,一种特定的付款方式。输入折扣码不是。这是您在付款时可以做的额外事情。

于 2014-12-10T00:15:41.137 回答