How to model optional actions on UML activity diagram - uml

After searching the net and a couple of old fashioned books I own, I still haven't found my answer to how to model an activity for a specific use case.
I am fairly new to UML and thus activity diagrams.
The activity is Add hotel. This is fictional, but the issue is exactly the same as my issue. My contract prevents me from talking about the real deal to third parties.
In this activity the user provides necessary details and has two optional actions that he can choose at anytime while in the Add hotel activity:
Add hotel chain
Add loyalty program
As said these are optional and not mandatory. The user is also able to proceed to save the entered data.
However, when choosing one of these actions, I imagine another activity diagram should be invoked, named the same as the choice the user made. In this activity all relevant stuff is entered and at the endpoint the user returns to the Add a hotel activity after which the user has the option to choose the optional activities again or proceed to save the provided data.
The only somewhat relevant answer I found was this one
But as I understand it, a fork means all actions after it have to be carried out before the flow will continue after the join.
And in case of a decision, only one option can be chosen.
The actions 1 and 2 above, are also available from other locations in the application. I just need to make them available on the Add hotel activity.
So how would I go about modelling optional actions that are available all the time during the flow of an activity? And why should it be done that way (if not obvious after reading)
Also, does it matter if these optional actions are Atomic actions or CallBehavior actions?
Like is said, I'm fairly new to UML, so it might well be possible that I interpret some things wrongly.

You're correct in the assumption that a fork will continue in all paths. To make an optional process simply use a Decision node (looks like a lozenge). From there you can proceed to your two optional actions or skip. Finally join the path again with the very same lozenge to merge the optional paths.
Basically it might look like this (not taking all the details of your activity into account):
Just ignore all those fuzzy details about different actions. Atomic is enough for a start.

Related

Use case diagram extend or include for admin relation to customer order

So basically i'm wondering if I'm thinking correctly. In an e-commerce environment does the order of a product have a relationship to the admin use case of managing orders? Once an order has gone through is the admin then going to be able to see the order through a relationship between the 2 use cases. I've provided an image for reference in my case.Here is the image
TL;DR
No, there is no extension here. Those will be two separate UCs.
Explanation
First let me focus on the goal of the Use Case diagram. This diagram is intended to show functions of the system and users (or more broadly actors) engaged in those functions. It is not used to show how data flow through the system or what are steps of the processing. There are other diagrams to do that.
As a rule of thumb, something is a good use case if you can log into the system, perform only the action of this single use case and then log out.
Extends (Includes works pretty much the same, it's just stronger) means that when you run the extended UC you can include the other use case as well. In other words in your specific example when Customer logs to E-Commerce to place an order he can while placing an order also choose to additionally receive and manage order (BTW I would reconsider this UC, you probably have few separate UCs here like Complete order, Dispatch order or Reject order) in which case additionally an Admin is need. Even if you invert Extends, it's still not what you want. Those two UC happen totally separately even though the order processed by Admin is the very same one placed by Customer.
I did not search for too long but I did not find a case where a given use case, associated to one actor, is extended or included by another use case, associated to another actors.
A use case describe the usage of your system by a given actor so you do not have any other actor involved.

How can one model an unconditional decision in an activity diagram?

For example, the user can perform action A, action B or action C in a tool. Whether they choose A, B or C, the order of these actions and how many times they are repeated is up to the user and the reason why they choose A,B or C and why they are chosen in a particular order isn't clear. Also any action can be repeated again after another action has been done by the user.
EDIT: A more concrete example would be the creation of an image. The user can draw a shape, choose a new shape, choose a new colour and save the image. While drawing these 4 actions can be performed intertwined in any random order and in any random quantity, only guided by the whims of the user.
There is also the choice of creating a new image from scratch or editing an existing image to create a new image.
Very simple solution to you question is below.
Please do not omit the guards after decision node if you don't want to have an undeterministic behaviour of your activity. Decision node offers a token to the first flow that have true guard whereas the order of evaluating of the guards is not defined.
When modelling anything using any notation, it is important to remember what the purpose of is in creating the model, and who is going to use it.
If you simply omit the guards on arcs, then the model has no information describing how the system behaves. It cannot guide another developer to create the software, it does not record the intent of the designer.
The user is outside the system boundary, so the decision as to what action to perform is elsewhere. The system behaviour should be modelled as a condition of its state, inputs or events - these are what the system can operate on, and what developers expect to find in the UML model to guide them.
The exact UML construct used will depend on how that choice is communicated across the system boundary - an activity diagram may well not be the best way of communicating that, or you might use multiple diagrams for each interaction
The software being modelled does not make an unconditional choice, and the information in the model should reflect that with enough detail to be useful to the next person viewing it.
Normally a loop node should help you to solve your problem. If the flag isTestedFirst, the loop node is a while-do loop.
However this is not the easiest node of activity diagram.
It has three part : the setup part, the test part which is test at each iteration and the body part.
Maybe this image extracted from sparx documentation may help you :
Hope this help and maybe someone else may provide more details.
Well, you just leave away the guard:
Now the path can take any way. However, since there is a choice, it's the user taking the action and choosing the path he likes.
Edit Thinking a bit about the "natural" control flow it seems obvious, that preceding the ConditionalNode you find an action like Offer choice (e.g. in the concrete example of the OP: "draw", "choose shape", "choose color", etc.). So the outcome of the ConditionalNode is one of the users choices which in turn should have an appropriate guard. So the above is merely a sketch and can be regarded as incomplete. However, presenting this sketch to a reader would either make him "aha" or ask the question that came up my mind after thinking a while. Regardless of this, there will be just one path been taken after the ConditionalNode.

UML: activity diagram control flow

I have found in internet the following activity diagram:
I can't understand why from Recieve order action there are two control flows (to Ship order and Bill customer). Are they parallel? Then why there is NOT fork. How to understand this diagram? Please, explain.
This is simply a bad example.
Judging from the context there should be a fork to indicate that both Ship order and Bill customer should happen in parallel.
Then there should be a Join before Send confirmation to indicate that both flows should have finished before the Send confirmation is executed.
It's perfectly valid UML 2. The first action requires no tokens, so it can start immediately. When the first action finishes, it offers tokens to two other actions and they can start. The last action cannot start until all required tokens are offered. When the last action is done, the containing activity is also done.
Forks just copy tokens. Joins just merge tokens. Thus, forks and joins are often unnecessary.
Please see Conrad Bock's excellent series of articles on activity diagrams in the Journal of Object Technology.
I did not check if this is a recent amendment to the UML specification but the current version 2.5 (chapter 15.2.3.2) states (emphasis set on my own):
As an ActivityNode may be the source for multiple ActivityEdges, the same token can be offered to multiple targets. However, the same token can only be accepted at one target at a time (unless it is copied, whereupon it is not the same token, see ForkNodes in sub clause 15.3 and ExecutableNodes in sub clause 15.5). If a token is offered to multiple ActivityNodes at the same time, it shall be accepted by at most one of them, but exactly which one is not completely determined by the Activity flow semantics. This means that an Activity model in which non-determinacy occurs may be subject to timing issues and race conditions. It is the responsibility of the modeler to avoid such conditions in the construction of the Activity model, if they are not desired.
From that point of view, I would argue that #Jim L.'s answer might be deprecated. I assume that, at least in the current version of UML, the diagram in question does not reflect the modeler's intention. A fork seems to be not only the clean way but the only right way to go, now.

Is this a correct use case diagram?

I'm trying to write an use for shopping online . Customer can search for their desired item and add them to the shopping cart,but when they decide to check out, they need to log in with their account. But what happen if customer already logged in ? Is my diagram still correct ? If not, How can I modify it ?
Any use case must be connected to some actor(s). So, you should add connections.
The CheckOut use case is strange and inunderstandable. I don't know any action in net stores, that includes both login and payment. If you mean ordering, the login or payment are additional separate use cases, that are connected to ordering by some conditions that could be described as states.
Don't forget, you can't show sequences of actions and states by use cases elements only. If you have a small use case diagram, you could include state machine diagrams in it, but here it is not good - You have totally forgotten the admin and seller actors and their use cases, so the full use case diagram will be too large to add something extra in it. Describe sequences about logging in additional State Machine diagrams.
You are trying to use the use case diagram as a workflow editor, which is incorrect.
Use case diagrams are used to indicate the actions that a user can take to accomplish something. They do not represent the sequence of these actions. Each use case starts from a specific user action, and not as a side effect of another use case.
In your diagram, the "Search" use case is fine, but the display of the result is part of that use case. It would not be very useful if the system would just display a "search complete" result and then force the user to do some action to view the result... Although you have an <<include>> relationship, that it not what it means.
One example for <<include>> is one for a Login use case. The Customer could login on their own before doing anything else or the login could be triggered by another use case, such as Check Out. Login would therefore be a use case on its own and it would also be <<include>> by the Check Out use case.
Add to Cart is a use case that should be triggered directly by the Customer. It is not something that is triggered automatically - the Customer needs to do something.
The same applies to the Make Payment use case. I would think that the Customer needs to perform an explicit action in order to pay.

Implementing Udi's Fetching Strategy - How do I search?

Background
Udi Dahan suggests a fetching strategy as a useful pattern to use for data access. I agree.
The concept is to make roles explicit. For example I have an Aggregate Root - Customer. I want customer in several parts of my application - a list of customers to select from, a view of the customer's details, and I want a button to deactivate a customer.
It seems Udi would suggest an interface for each of these roles. So I have ICustomerInList with very basic details, ICustomerDetail which includes the latest 10 products purchased, and IDeactivateCustomer which has a method to deactivate the customer. Each interface exposes just enough of my Customer Aggregate Root to get the job done in each situation. My Customer Aggregate Root implements all these interfaces.
Now I want to implement a fetching strategy for each of these roles. Each strategy can load a different amount of data into my Aggregate Root because it will be behind an interface exposing only the bits of information needed.
The general method to implement this part is to ask a Service Locator or some other style of dependency injection. This code will take the interface you are wanting, for example ICustomerInList, and find a fetching strategy to load it (IStrategyForFetching<ICustomerInList>). This strategy is implemented by a class that knows to only load a Customer with the bits of information needed for the ICustomerInList interface.
So far so good.
Question
What you pass to the Service Locator, or the IStrategyForFetching<ICustomerInList>. All of the examples I see are only selecting one object by a known id. This case is easy, the calling code passes this id through and will get back the specific interface.
What if I want to search? Or I want page 2 of the list of customers? Now I want to pass in more terms that the Fetching Strategy needs.
Possible solutions
Some of the examples I've seen use a predicate - an expression that returns true or false if a particular Aggregate Root should be part of the result set. This works fine for conditions but what about getting back the first n customers and no more? Or getting page 2 of the search results? Or how the results are sorted?
My first reaction is to start adding generic parameters to my IStrategyForFetching<ICustomerInList> It now becomes IStrategyForFetching<TAggregateRoot, TStrategyForSelecting, TStrategyForOrdering>. This quickly becomes complex and ugly. It's further complicated by different repositories. Some repositories only supply data when using a particular strategy for selecting, some only certain types of ordering. I would like to have the flexibility to implement general repositories that can take sorting functions along with specialised repositories that only return Aggregate Roots sorted in a particular fashion.
It sounds like I should apply the same pattern used at the start - How do I make roles explicit? Should I implement a strategy for fetching X (Aggregate Root) using the payload Y (search / ordering parameters)?
Edit (2012-03-05)
This is all still valid if I'm not returning the Aggregate Root each time. If each interface is implemented by a different DTO I can still use IStrategyForFetching. This is why this pattern is powerful - what does the fetching and what is returned doesn't have to map in any way to the aggregate root.
I've ended up using IStrategyForFetching<TEntity, TSpecification>. TEntity is the thing I want to get, TSpecification is how I want to get it.
Have you come across CQRS? Udi is a big proponent of it, and its purpose is to solve this exact issue.
The concept in its most basic form is to separate the domain model from querying. This means that the domain model only comes into play when you want to execute a command / commit a transaction. You don't use data from your aggregates & entities to display information on the screen. Instead, you create a separate data access service (or bunch of them) that contain methods that provide the exact data required for each screen. These methods can accept criteria objects as parameters and therefore do searching with whatever criteria you desire.
A quick sequence of how this works:
A screen shows a list of customers that have made orders in the last week.
The UI calls the CustomerQueryService passing a date as criteria.
The CustomerQueryService executes a query that returns only the fields required for this screen, including the aggregate id of each customer.
The user chooses a customer in the list, and chooses perform the 'Make Important Customer' action /command.
The UI sends a MakeImportantCommand to the Command Service (or Application Service in DDD terms) containing the ID of the customer.
The command service fetches the Customer aggregate from the repository using the ID passed in the command, calls the necessary methods and updates the database.
Building your app using the CQRS architecture opens you up to lot of possibilities regarding performance and scalability. You can take this simple example further by creating separate query databases that contain denormalised tables for every view, eventual consistency & event sourcing. There is a lot of videos/examples/blogs about CQRS that I think would really interest you.
I know your question was regarding 'fetching strategy' but I notice that he wrote this article in 2007, and it's likely that he considers CQRS its sucessor.
To summarise my answer:
Don't try and project cut down DTO's from your domain aggregates. Instead, just create separate query services that give you a tailored query for your needs.
Read up on CQRS (if you haven't already).
To add to the response by David Masters, I think all the fetching strategy interfaces are adding needless complexity. Having the Customer AR implement the various interfaces which are modeled after a UI is a needless constraint on the AR class and you will spend far to much effort trying to enforce it. Moreover, it is a brittle solution. What if a view requires data that while related to Customer, does not belong on the customer class? Does one then coerce the customer class and the corresponding ORM mappings to contain that data? Why not just have a separate set of classes for query purposes and be done with it? This allows you to deal with fetching strategies at the place where they belong - in the repository. Furthermore, what value does the fetching strategy interface abstraction really add? It may be an appropriate model of what is happening in the application, it doesn't help in implementing it.

Resources