【问题标题】:Use case generalization versus extension用例泛化与扩展
【发布时间】:2013-02-28 10:51:30
【问题描述】:

UML 用例图允许两种看似等效的方式来显示给定的用例可能以几种不同的方式实现,即use case generalizationsuse 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 图。关于使用这两者中的哪一个,是否有硬性规定?如果是,那是什么?

【问题讨论】:

  • 两种实现都模拟了相同的问题。它们与一个或多个 UC 图表无关。多态的更受欢迎,因为它更简单、更容易扩展并且更少受人为错误的影响。

标签: uml use-case


【解决方案1】:

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

确实如此。

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

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

对于这样的实施来说,用例阶段是不是太早了 要建模的具体问题?

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

还有更合适的 UML 图表。

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

对于哪一个有硬性规定吗? 这两个要使用,如果是,它是什么?

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

【讨论】:

    【解决方案2】:

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

    另一方面,泛化(不仅为用例定义,也为任何分类器定义)是一个更广泛的概念,因为它没有详细说明(在图表级别)何时以及如何进行专门化行为的细节被执行。如果“Pay via Paypal”是“Make Payment”的一种特殊化,它将重新定义“Make Payment”的行为,这可能与“Pay via credit card”的行为有很大不同。

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 我明白你在说什么。 Make Payment 本身并不完整,因此最自然的使用关系是泛化(无论如何这是我喜欢的)。然而,使用泛化似乎意味着不可能同时使用多种支付方式。 Some people 说添加对包含关系设置条件的功能将有助于避免这些问题。你的想法?
      • 我已经查看了作者在您的链接中所述的问题。有一个简单的解决方案。仔细想想,“一次”两种方式的支付其实就是两次支付。作者对多种支付方式必须一次通过付款用例的想法感到困惑。您可以为每种付款方式制作一张通行证。如果您想将多个支付交易链接到单个逻辑支付中,请扩展 Make Payment 用例,添加“处理多种付款方式”用例或类似的用例,通过 Make Payment 链接多次传递。
      • 另外,虽然我现在看到了可能使用扩展来处理多个支付的观点,但我仍然认为使用泛化模型更准确。使用 extends 并不能清楚地区分单一支付方式和多种支付方式。
      • 谢谢@BobRodes 我同意概括是要走的路,我正在寻找的是一个(经验法则)规则,它表明一种方法何时比另一种更合适。
      猜你喜欢
      • 1970-01-01
      • 2022-11-09
      • 2012-10-19
      • 2015-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多