28

UML Use Case Diagrams allow for two seemingly equivalent ways to show that a given use case might be realised in several different ways namely use case generalizations as opposed to use case extensions. I have seen the following basically example modelled using either approach with equal frequency, sometimes within a single source.

Use case generalisation image

Use case extension image

To my mind an extension is a weaker relationship than generalization as a direct substitution of the specialised use case for the base case must be possible in generalization but not necessarily in extensions.

It seems to me that generalisation implies a polymorphic implementation is desired while extension implies some branching structure is to be used.

void makePayment(const PaymentDetails* pd)
{
   pd->pay();
}

as opposed to

void makePayment(const PaymentDetails* pd)
{
   switch(pd->type)
   {
       case EFT:
                payViaEFT(pd); 
                break;
       case PAYPAL:
                payViaPayPal(pd); 
                break;
       case CREDITCARD:
                payViaCreditCard(pd); 
                break;
   }
}

Isn't the Use Case stage far too early for such implementation specific concerns to be modelled? There are much more appropriate UML diagrams for that. Is there a hard and fast rule regarding which of the two to use and if so what is it?

DuncanACoulter
  • 2,095
  • 2
  • 25
  • 38
  • 1
    Both implementations model the same problem. They aren't associated with one UC diagram or another. The polymorphic one is much more desirable, as it is simpler, easier to extend and less subject to human error. – André Willik Valenti May 04 '15 at 18:55

3 Answers3

19

To my mind an extension is a weaker relationship than generalization as a direct substitution of the specialised use case for the base case must be possible in generalization but not necessarily in extensions.

That is true.

It seems to me that generalisation implies a polymorphic implementation is desired while extension implies some branching structure is to be used.

The diagram does not dictate any implementation. You can interpret a hint from the diagram for yourself, though. UML remains independent of language and solution there.

Isn't the Use Case stage far too early for such implementation specific concerns to be modelled?

Well, as indicated above, UML does not enforce any specific kind of implementation. However, you are gathering some important functional requirements here that might greatly influence your time schedule and workload. ("Pay with credit card" is way more complex to handle than "pay in advance by bank transfer"). So you'd strive to capture that but remain open to different solution approaches.

There are much more appropriate UML diagrams for that.

You can really use them in parallel :) as they are different views on the same subject.

Is there a hard and fast rule regarding which of the two to use and if so what is it?

I prefer the generalization in this case because the extensions falsely suggest there could be a way of paying without using any of the three named options. As you indicated yourself.

Addendum (as per comments): The high-level purpose of the example diagram is to outline the foreseen payment means. A payment needs at least one means (unless payment is cancelled), just like "print" is too vague without clarifications such as "what" and "where". Hence my preference for using the generalization, despite "make payment" being a valid use case in itself.

observer
  • 2,925
  • 1
  • 19
  • 38
  • As to your last remark: None of the specialized UCs takes over precedence. There is no _abstract_ UC (which `Make payment` had to be for your conclusion). Rather the course of events will exactly tell which payment UC to take. Even none if you cancel the payment. Or multiple if that's desired. – qwerty_so Jun 08 '22 at 18:19
  • Thanks. Funny to see the first comment after almost 10 years :) The high-level purpose of the example diagram is to outline payment _means_. A payment always needs a means, just like "print" is too vague without clarifications such as "what" and "where". For that reason I had outlined this preference. But of course, you are right: There could be multiple payment means involved (e.g. partial payment by gift card + remaining sum via paypal) – observer Jun 08 '22 at 18:33
  • Yeah :-) I only was guided here from "I also read...". Even more funny that you reacted so fast since you don't seem to be that active. If you'd clarify the last part I'd give an upvote. (wink, wink, nudge, nudge) – qwerty_so Jun 08 '22 at 19:55
  • 1
    Edited accordingly. – observer Jun 09 '22 at 15:50
11

When modelling with an extend relationship, the extending use case (pay via xxx) is executed when the extended use case (make payment) is at a precise location (given by the extension point, payment type) if the condition for such extend relationship holds (e.g. for "Pay via Paypal", the condition would be payment_type=PAYPAL). In this model, "Pay via Paypal" does only deals with the details of completing a payment transaction with Paypal, while "Make Payment" specifies all the behaviors that are independent of the payment method (such as computing the total amount, and saving the result of the transaction once that it was performed).

On the other hand, generalization (which is defined not only for use cases, but also for any classifier) is a broader concept, since it do not detail (at the diagram level) the details of when and how the specialized behaviors are executed. If "Pay via Paypal" were a specialization of "Make Payment" it would redefine the behavior of "Make Payment", which could be substantially different from the behavior of "Pay via credit card".

Being an extending use case does not means that the alternatives have to be hardcoded. Indeed, your first example is also a valid implementation of a extend relationship, since pd->pay(pd) will invoke different behaviors depending on the selected payment type. Actually, use case diagram models what a system is supposed to do, while low-level implementation details are better specified in activity diagrams.

Javier
  • 12,100
  • 5
  • 46
  • 57
8

An example of an extension would be a "Discount Payment" use case. Discounting a payment has to do with making a payment, but you don't have to discount a payment in order to make the payment.

You can look at the "is a" relationship to make the determination of which to use. Pay by PayPal "is a" make payment, a specific way of making a payment. Discounting a payment isn't. It's something additional you can do while making a payment.

BobRodes
  • 5,990
  • 2
  • 24
  • 26
  • I see what you are saying. Make Payment isn't complete by itself so the most natural relationship to use would be generalisation (which is what I favour anyway). However using generalisation would seem to imply then that it is not possible to use multiple forms of payment at the same time. [Some people](http://www.uml-diagrams.org/use-case-include.html) say that adding the ability to place conditions on include relationships would be helpful to avoid these problems. Your thoughts? – DuncanACoulter Dec 22 '14 at 11:33
  • I've looked the problem as stated by the author in your link. There's an easy solution. If you think about it, "a" payment with two methods is actually two payments. The author is getting hung up on the idea that multiple payment methods have to be a single pass through the make payment use case. You can make one pass per payment method. If you want to link multiple payment transactions into a single logical payment, then extend the Make Payment use case, adding a "Process Multiple Payment Methods" use case or some such, which links multiple passes through Make Payment. – BobRodes Dec 22 '14 at 14:58
  • 2
    Also, while I see the point now about possibly using extends to handle multiple payments, I still think that using the generalization model is more accurate. Using extends doesn't distinguish between single and multiple payment methods as clearly. – BobRodes Dec 22 '14 at 15:05
  • Thanks @BobRodes I agree that generalization is the way to go, what I was looking for was a rule (of thumb) which indicates when one approach is more appropriate than the other. – DuncanACoulter Jan 04 '15 at 09:33
  • 1
    Just stumbled over this. 'Enter Discount Code' is not a use case! This is some action which might appear in a use case. What would be the added value for this "use case"? None! Like for `Login`. – qwerty_so Jun 08 '22 at 18:13
  • 1
    @qwerty_so Yeah, six years later, it doesn't look like one to me either. Perhaps "Discount" or "Discount Payment" is a better name. – BobRodes Jun 09 '22 at 19:52
  • I'd prefer a verb/substantive version in any case :-) Maybe Pay with discount? – qwerty_so Jun 09 '22 at 21:04
  • 1
    @qwerty_so That seems to work. I am using "discount" as a verb here, though, so maybe mine works too. – BobRodes Jun 10 '22 at 22:37
  • You might consider to fix the answer... – qwerty_so Jun 11 '22 at 08:35
  • 1
    @qwerty_so Done. I talk a lot about not confusing what to do with how to do it when defining requirements, and it looks like I didn't take my own advice here! It looks like we've made an improvement. :) Thanks for your input. – BobRodes Jun 12 '22 at 13:19
  • Believe it or not: the same happens to me ;-) – qwerty_so Jun 13 '22 at 08:05
  • 1
    @qwerty_so I would be skeptical of anyone who said otherwise. :) – BobRodes Jun 13 '22 at 20:21