I am trying to learn UML 2, specifically activity diagram and I am little bit confused about using events over activities.
So my question is - When it is necessary to use accept event over activity or where is it more convenient ?
Thank you for any help.
Events happen "out of order" while Actions (not Activities!) appear in a controlled flow where the flow is controlled by conditions. The "out of order" can be timers or exceptions (like in the last example here).
Note: an Activity is a sequence of Actions (short pieces of things done in one place so they have some elementary meaning). You can use an Activity within Actions only if you use it as Invocation. It will look like this:
An accept event can handle unsolicited input. This might be an "urgent call", a "flash stroke", or something like that. If that event happens, a new token is created and control flow will continue in parallel with the "normal flow". In order to cancel the normal flow you need to create an interruptible region (like in the above example) and exit from the region thereby destroying the "normal" token flow.
Related
I am developing a simple microservice that has a cyclical nature:
waits until someone pubblish a message on an MQTT topic
performs actions
sends a reply and then waits for the next message
I need to share with others all the steps of creating this microservice.
I was thinking of using an activity diagram but all the examples I found don't seem to cover this type of behavior.
What is the more appropriate UML diagram to describe cyclic operation and why?
One thing to keep in mind is that there is no command to stop receiving messages, it starts receiving as soon as it is started and stops only when it is terminated.
You decribe the details of an activity that is best modelled with an activity diagram.
There are more than one way to model your case. For example:
The cyclic nature of what you describe is already an implementation view: you imagine a loop in your code that repeats the steps. You can show such a control flow in your diagram if you want.
You could as well model a single iteration as an activity, and consider that the activity starts when there's something to process.
Finally, you could use object flow and their build-in bufering capabilities to model the full system including your queue.
This is best modeled by using an activity diagram.
Waiting for an incoming message can be modeled by an Accept Event action. Sending back a reply can be modeled by a Send Signal action.
The pictures below are almost equivalent. The left picture starts processing an incoming message even when the processing of the previous message has not yet ended. The right picture waits for the previous message to be fully processed and then starts accepting a new message.
I would recommend the picture on the left, because it is the simplest. If you want to stress the cyclical nature, or if it is important to convey that the service only processes messages one by one, you could choose the picture on the right.
I'm working on a project and trying to show one of the Use Cases in a UML activity diagram.
I'd like to use it in order to show that the requirements for this particular use case are met.
I'd also like to use it to develop the test cases that will need to be written for this use case.
I've ordered the "UML 2.0 In A Nutshell" book but until that arrives I'm trying my best from articles and youtube clips so the diagram may not conform to the proper standards.
Question 1:
I've tried to show that the ExecuteInThread function as a whole has a try catch block to stop any exception bubbling up and crashing the app but I'm not sure if I've shown that correctly?
Question 2:
I'd also like to show is that updating the task status to Failed / In Progress / Completed is done on the database and if the database is unavailable it retries 10 times to connect before it fails.
Is it possible to have a repeatable block on the side I could refer to for each Update activity to show this?
Question 3:
I've read that at the level of the use case I should not be showing any implementation details.
I'm guessing this means avoid showing there's a database involved at all and not to show any try / catch logic unless it impacts the user's actions. Am I doing completely the wrong thing here?
The retry logic is a requirement for this use case though so my first attempt was to include it given it would help with writing the test cases and showing application resilience.
Diagram:
Question 1:
Any action can be protected by an exception handler. This is the zigzag-line in your diagram. The action at the other end is the handler body. I must not have incoming or outgoing control or object flows. When the exception handler finishes, the protected action produces tokens on its outgoing flows, as if it has ended normally. The handler body should also have an input pin typed by the exception. This way it can distinguish different exceptions and the protected action can tranfer information about the problem.
Structured activity nodes are also actions and can be protected by an exception handler. In your diagram I guess Execute Task in Thread is such an action. The official notation uses a dashed border and the keyword «structured».
Edit: After discussion with #bruno.
If you want to use Exceptions, you should probably rethink how you group the actions. A protected action will always finish successfully, if its exception handler body doesn't raise a new exception. That means the body must try to recover from the exception and potentially retry the behavior of the protected action (there is no UML element for retrying, you will have to do it on foot). If that doesn't work, the handler body must reraise the exception (after having made sure that everything is in good order, i.e. that the class invariant is still holding).
This might seem a bit over complicated. Why not simply use a decision node after the action execute task with the guard [successfull]. I would use ReceiveSignalActions in use case flows only to model interactions from outside of the system, that can influence the flow of the use case.
Question 2:
You can create an activity update task status and call it from all the update actions. The status itself could be a value pin on this call action. Inside the update activity you can show a loop with decision and merge nodes that counts the trials. However, it will probably be easier to just write in the description, that it can be Irepeated 10 times.
This is the way how a repeatable set of actions can be modeled. It is not possible to do that in the same diagram. I would however be allowed to expand one of the call actions, so that the called activity is shown there. You have to try, whether your tool does offer this possiblity. Some tools only offer to show any diagram embedded in another diagram. This is not standard and will not be interchangable between tools.
Question 3:
I agree that the database and the number of retries are technical details that are not the focus of the use case analysis.
It could be interesting, though, if the system would not just display an error message, but would need to offer alternative ways to achieve the desired result. If for example the system shall then offer to save the update to an usb stick. Since this requires additional interaction with the user and gives rise to a new functional requirement for the system, it makes sense to analyse it within the use case. If it is just an occasional technical problem, I would not cover it.
If you need a way to capture this requirement in your model, I would just add a user defined extension for textual requirements. Not all requirements are coming from use cases. Many tools already have their own extension for this.
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.
Imagine that you have a simplistic GUI application. When you open it, there is an input box and a button placed on the application window. When you press the button you should see the entered value displayed in a popup message box. Of course, the button can be clicked without entering the value into the input box. Another possibility is that user exits the application right after opening it.
How-do you model this in UML activity diagram?
The typical UML elements like
a) decision node
b) fork/join node
do not seem appropriate to me.
According to my understanding a) is used when a check on certain set property is made and according to the outcome, the flow is routed somewhere; this is not appropriate since no checks are made
b) is not appropriate since it assumes parallel execution (?) which is not the case in the modeled situation.
There is a similar question here on SO though I don't understand what is meant by the suggested "Event element" in the accepted answer.
This seems not appropriate for a useful activity diagram:
Of course, the button can be clicked without entering the value into the input box.
Then there was no noteworthy activity, so nothing to model.
Another possibility is that user exits the application right after opening it.
Same here.
Most aspects of UML are rather GUI-unaware. You want to not spend your time modeling trivial cases but instead focus on actual workflows. Such diagrams will add way more value.
Nevertheless if you were to model something for your example, your assumption is basically right. The input validation is not bound to the willing user decision of leaving an input blank, though. You gotta do it anyway.
It is possible.
Use call operation for operation invocation on classes instance which represent GUI elements and also use Accpet Event Actions to receive events from GUI elements.GUI elements should be defined as standard classes. See Action Model part in UML Superstructure document. UML Website
It's a very interesting question. As already said in the previous post, a UI typically receive events and send informations in a visual form.
So, the particular UML actions (activity diagram) like "accept event" and "signal sending" are appropriate when the UI can receive different s events in no predefine order. Activity diagram are generally based on a "scenario" point of view, showing some scenarios but not all. Make events oriented activity diagram is more difficult; sometimes, "interruption region" have to be used.
I guess this question could be related to any evented system like Event sourcing / DDD / Lambda architecture, ESB, Actors... I tagged the question so that people experienced with these systems could answer.
I'm currently experimenting with my startup an original way to build user interfaces, by using concepts often used in DDD / Event sourcing world but applied to a javascript single page application. What I want is a purely functional UI, where I can replay the in-memory event log to restore the UI state (the event log is not persisted on browser close, it is just to make things easy to reason about and potentially enable cool features like UI undo/redo for free, time travelling debugger like in ELM...)
I just wonder sometimes how to choose the right level of abstraction for events as it seems to me there may be multiple "interpretations" of something that just happened.
Basically, in a JS SPA, many events are triggered after an user has clicked on a button, on a link or something like that. So I could add an entry to my event log being this low-level event (after managing to make it serializable). But this event can also be interpreted as a representation of what the user really has done in a high level abstraction.
To give an exemple, let's say I have on my UI a popup that is displayed at some point.
When the user clicks anywhere outside of the popup, it should be closed.
Let's imagine now the user clicks to a div outside of the popup to close it. What event abstraction level am I supposed to add to the event log?
User has clicked on div ?
User has clicked outside of the popup ?
User has closed the popup ?
These 3 event abstractions seems correct to me: they describe in the past something that happened, but at different abstraction levels. So I'm asking myself some questions like:
Do I have to choose one of the 3 abstraction level? If so how to choose?
Can or should I fire all 3 events? If so, wouldn't the event log becomes a bit messy?
Should I use concepts like DDD Saga, so that when receiving a "user clicked div" event, the Saga could fire a "close popup" command or something?
In an example described, I would suggest to not generate any events at all, because you are not performing any command (action which changes application state). You may want to have such event only in situation when there is actually a practical value of saving it, or you can think of it becoming valuable in the nearest future, so you can use all this information to generate some kind of report which will become valuable for your business.
There is no hard and fast rule behind that, it's just a matter of common sense. What kind of problem are you trying to solve? If it's implementing redo/undo, event sourcing is not the first thing that you should look for, "command" pattern would probably be a better choice. You will not get undo/redo "for free" with just event sourcing. Consider splitting your answer into multiple ones and be more specific about practical goal.
Also, my advice would be to stay away from SAGAs as long as you can. It's always better to perform things synchronously where possible, otherwise your code will quickly become a mess (less readable, growing semantic distance). If you have to make it async, the better alternative would be utilizing "continuation passing style","promises". Sagas should be considered as a last resort and used when all other approaches failed to work ... but such scenarios are more likely to crop up on a server side, when your lovely noSql thing does not support ACID transactions, for example :p.
Correct me if I'm wrong, but looks like you just want to play with a "new trendy approach" and try it without any practical reason. It's fine, as long as you are ok with making your application more complex than it should be. (more expensive to develop and support)