UML用例图允许两种看似等效的方式来表明给定的用例可能以几种不同的方式实现,即use case generalizations而不是use case extensions。我已经看到以下基本示例使用相同频率的任一方法建模,有时在单个源中。
在我看来,扩展是一种较弱的关系,而不是泛化,因为基本情况的专用用例的直接替换必须可以推广,但不一定是扩展。
在我看来,泛化意味着需要多态实现,而扩展意味着要使用一些分支结构。
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图表。关于两者中的哪一个使用是否存在硬性规定?如果是,那么它是什么?
答案 0 :(得分:12)
在我看来,延伸是一种比一般化更弱的关系 作为基础案例的专用用例的直接替代 必须有可能推广,但不一定是扩展。
这是真的。
在我看来,泛化意味着多态 期望实现,而扩展意味着一些分支 结构将被使用。
该图没有规定任何实现。 但是,您可以自己解释图中的提示。 UML仍然独立于那里的语言和解决方案。
对于此类实施而言,用例阶段不是太早 具体问题需要建模吗?
好吧,如上所述,UML不强制执行任何特定类型的实现。 但是,您正在收集一些可能会极大地影响您的时间安排和工作量的重要功能要求。 (“使用信用卡付款”比“通过银行转帐提前支付”更复杂。)因此,您将努力捕捉这一点,但仍然对不同的解决方案方法持开放态度。
有更合适的UML 图表。
你可以真正并行使用它们,因为它们是同一主题的不同观点。
关于哪一个,是否存在严格的规则? 两个使用,如果是,它是什么?
我更喜欢这种情况下的概括,因为实际上扩展错误地暗示可以有一种方式来支付而不使用任何三个命名选项。正如你所说的那样。
答案 1 :(得分:8)
当使用扩展关系进行建模时,如果扩展用例(付款)位于精确位置(由扩展点,支付类型给出),则执行扩展用例(通过xxx支付)延长关系成立(例如,对于“通过Paypal支付”,条件将是payment_type = PAYPAL)。在此模型中,“Paypal Paypal”仅处理与Paypal完成支付交易的详细信息,而“Make Payment”指定与支付方法无关的所有行为(例如计算总金额,并保存一旦执行了交易的结果)。
另一方面,泛化(不仅针对用例而且针对任何分类器定义)是一个更广泛的概念,因为它没有详细说明(在图级别)特定行为的时间和方式的详细信息执行。如果“通过Paypal付款”是“付款”的专业化,它将重新定义“付款”的行为,这可能与“通过信用卡付款”的行为大不相同。
作为扩展用例并不意味着替代方案必须是硬编码的。实际上,您的第一个示例也是扩展关系的有效实现,因为pd->pay(pd)
将根据所选的付款类型调用不同的行为。实际上,用例图模型系统应该做什么,而在活动图中更好地指定了低级实现细节。
答案 2 :(得分:4)
扩展的一个例子是"输入折扣代码"用例。输入折扣代码与付款有关,但您无需输入折扣即可进行付款。
你可以看一下"是一个"关系决定使用哪个。通过PayPal付款"是"付款,一种特定的付款方式。输入折扣代码isn&t; t。这是您在付款时可以做的其他事情。