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


在我看来,扩展是一种比一般化更弱的关系,因为基本情况的专用用例的直接替换必须是概括的,但不一定是扩展.
在我看来,泛化意味着需要多态实现,而扩展意味着要使用一些分支结构.
void makePayment(const PaymentDetails* pd)
{
pd->pay();
}
Run Code Online (Sandbox Code Playgroud)
而不是
void makePayment(const PaymentDetails* pd)
{
switch(pd->type)
{
case EFT:
payViaEFT(pd);
break;
case PAYPAL:
payViaPayPal(pd);
break;
case CREDITCARD:
payViaCreditCard(pd);
break;
}
}
Run Code Online (Sandbox Code Playgroud)
针对此类实现特定问题的建模是否过早的用例阶段?有更合适的UML图表.关于两者中的哪一个使用是否存在硬性规定?如果是,那么它是什么?
obs*_*ver 14
在我看来,扩展是一种比一般化更弱的关系,因为基本情况的专用用例的直接替换必须是概括的,但不一定是扩展.
那是真实的.
在我看来,泛化意味着需要多态实现,而扩展意味着要使用一些分支结构.
该图没有规定任何实现.但是,您可以自己解释图中的提示.UML仍然独立于那里的语言和解决方案.
针对此类实现特定问题的建模是否过早的用例阶段?
好吧,如上所述,UML不强制执行任何特定类型的实现.但是,您正在收集一些可能会极大地影响您的时间安排和工作量的重要功能要求.("使用信用卡付款"比"通过银行转帐提前支付"更复杂.)因此,您将努力捕捉这一点,但仍然对不同的解决方案方法持开放态度.
有更合适的UML图表.
您可以真正并行使用它们:)因为它们是同一主题的不同视图.
关于两者中的哪一个使用是否存在硬性规定?如果是,那么它是什么?
我更喜欢这种情况下的概括,因为实际上扩展错误地表明可以有一种方式来支付而不使用任何三个命名选项.正如你所说的那样.
当使用扩展关系进行建模时,如果扩展用例(付款类型)处于精确位置(由扩展点,支付类型给出),则执行扩展用例(通过xxx支付) (例如,"通过Paypal支付",条件是payment_type = PAYPAL).在此模型中,"Paypal Paypal"仅处理与Paypal完成支付交易的详细信息,而"Make Payment"指定与支付方法无关的所有行为(例如计算总金额,并保存一旦执行了交易的结果).
另一方面,泛化(不仅定义用例,而且定义为任何分类器)是一个更广泛的概念,因为它没有详细说明(在图级别)有关何时以及如何执行特定行为的详细信息.如果"通过Paypal付款"是"付款"的专业化,它将重新定义"付款"的行为,这可能与"通过信用卡付款"的行为大不相同.
作为扩展用例并不意味着替代方案必须是硬编码的.实际上,您的第一个示例也是扩展关系的有效实现,因为pd->pay(pd)将根据所选的付款类型调用不同的行为.实际上,用例图模拟了系统应该做什么,而在活动图中更好地指定了低级实现细节.
扩展的一个例子是“输入折扣代码”用例。输入折扣代码与付款有关,但您不必输入折扣代码即可付款。
您可以查看“是一个”关系来确定使用哪个。Pay by PayPal“是一种”付款方式,一种特定的付款方式。输入折扣代码不是。这是您在付款时可以做的其他事情。