I want to draw uml-correct activity diagram representing process of my raytracer.
I know I should use black rectangles to model fork/join. But in my application I spawn N threads doing the same thing (which is not simple and will be modeled via multiple activity elements). How can I draw such activity diagram without having the same thing without knowing number of threads?
My explanation is poor, image may help understand what I want to model with activity diagram
You can use the expansion region element.
There is no way I know of to model a fork of N control flows and I found none in three UML2 books nor the UML2.4.1 formal specification (http://www.omg.org/spec/UML/2.4.1/Superstructure).
That said, using an expansion region with the 'parallel' keyword, you can fork N object flows, processing N objects in parallel.
I am, however, not fully satisfied with this solution because I suspect that you don't create N threads because you have N objects to process but because you have N processor cores and that each thread processes a lot of frames (or whatever objects that need processing).
You can, of course, work around this by using the processor cores as objects.
Related
I want to model a method which occurs when a specified time has elapsed and an attribute which disappear with class and sequence diagram.
Here is the situation: Workers are working in a factory where they use machines. Each machine can be used by 0-10 workers. Every machine has a repair time limit whereupon the workers have to repair it. It also has a time limit whereupon if the workers miss the repair, the machine explode and the worker or workers dies (bigger then the first one). There are different machines. Some of them have longer time limit, some of them have shorter. All machines are machine oiled which lasts for a while and it gradually loses its strength until it disappears. This value the same for all machines.
My class-diagram:
I saw this solution for the repaireTime and explodeTime can handle with qualifires counting the elapsed time, but I do not see how does a tick increase the qualifiers value. Is it behave like an attribute like this?
At last, how does the machine oil disappear works? It is just an attribute what must be deleted but I do not understand where to count the elapsed time for this and then delete it.
EDIT:
Your sequence diagram appears to be fine.
Your class diagram is however misleading:
The class diagram is a structural diagram, and not a behavioral diagram. SO you don't really care for elapsed time unless it appears in a property or an operation.
The navigation arrow between Machine and Timer does not facilitate the proposed sequence diagram, which assumes that the Timer knows to find the Machine.
Isn't the association with worker end and with works end not the same associations in the end, if considered at the general level?
The qualifier for the elapsed time is not correct.
For the time based association between Machine and Worker, you could consider making this a many to many association, with an association class defining the time-slot (start and end time, from which you can calculate the duration). You may find here some information about how to work with timeslods (although you do not need the additional constraints mentioned in that other question).
Edit: review of your updated diagrams
The class diagram looks better. Some advices:
Class and Subclass1 are probably Machine and E1 ?
Is the duration association class specific to Subclass or is it general for any Class? In the latter case, you should draw it between Worker and Class. It is not necessary to repeat it for Subclass, since the specialisation automatically inherits the associations, properties and operations of its generalisation.
If the Timer has to send messages to objects? The dependency relation therefore seems misplaced. Shouldn't it then have an association with the classes to the instances of which it shall send messages?
How does the Timer know about new Duration objects ? Does it need to know Duration objects or couldn't it send ticks to the machines, which would forward the ticks to the durations?
On the sequence diagrams, and independently of the impact of the above-mentioned advices, it is important to realize that lifelines do not represent classes, but objects that belong to the classes. The class-names should therefore be preceded by a : or an object name and a :.
The second diagram would be integrated in the first diagram if you'd go for the tick forwarding. Nevertheless, if you'd keep it, you should ask yourself how a Duration could check if elapsed_time==timeExplode since timeExplode is a property of the machine and not of the duration.
A common multi-threaded implementation is to have some class where Method_A() is running in a thread and sits blocked waiting for some signal/event member variable (e.g. WaitForSingleObject).
Interacting classes running in different thread will then call Method_B() which does some work, sets the signal/event variable, perhaps does some more work, then returns.
How do I represent this interaction on a Sequence Diagram?
Should I have two lifelines, one for each thread, even though they are operating on the same instance of the class? My modelling tool (Enterprise Architect 12) doesn't allow the same class to appear twice on a Sequence Diagram, so seems to discourage this.
Edit: Geert has noted that the Sequence Diagram should use instances, not classes, which is a fair comment. However the problem is the same: multiple lifelines would imply multiple instances, but in the question Method_A() and Method_B() are operating on the same instance, just from different threads. How can that be represented?
The approach I have decided to take is to add two lifelines for the same instance, then label one lifeline with the <<thread>> stereotype and add the thread it runs in to the name:
I realise this is probably not standard UML, but it seems to get across all the information I want to express in a clear manner, which is the most important thing, right?
Martin Fowler does mention a few times in his book that sometimes a non-normative diagram is actually clearer. So that's my excuse. :)
(Edit You can solve it by just using asynchronous messages as #sim points out. That will just do. The answer below is showing what is going on under the hood. So if you don't care about the details, go with that answer.)
You are asking more a design than an UML question. Namely, how do concurrent instances talk to each other. You said first
Method_A() is running in a thread and sits blocked waiting
which simply means that it can not accept anything since it is blocked. Now, guessing from the context of your question, I assume that you still want to communicate with that instance since
in different thread will then call Method_B()
So, in order to be able to accept a message the instance must be in an appropriate state. There are a couple of ways to achieve that. One simple is, if the according OS has support for that, to return to the scheduler and tell him that it's waiting for some message.
Now when method_b is being called you know inside Object1 that you are in some kind of idle state inside method_a and do appropriate (return-) action.
Another way would be to poll the scheduler for incoming messages and handle them.
You need to keep in mind that sending a message usually not directly deals with the instance but tells the system scheduler to interact with the appropriate instance (at least in most OSs).
I just remember from the Modula2 compiler I once wrote that it has a concept of coroutines which allows a concurrent thread to run within the compiled code. But basically that is just mapped to two independent threads running under the hood of a semi-single one and you'd depict that with two life-lines when going into detail.
N.B.: Rather than method it should be operation (since that is was is invoked by a message; while the method is what is implemented inside the operation). And as per common convention they should start with a lower case char.
And also: do NOT use classes in a SD. Unfortunately EA still allows that (why? Ask them!). Somewhere hidden in their docs there is a sentence that you must use instances. Else the model will break. A SD is always (!) a sample sequence of instances talking to each other. Classes do not talk, they are just blueprints for the instances.
You should never use classes in sequence diagrams, but instead use instances/lifelines that have your class as classifier.
If you hold the control down when dragging a class to a sequence diagram you can choose to drop is as instance instead of as class.
This way you can add as many as you want for the same class.
The notation you are looking for is an asynchronous message. You could theoretically express this using a single lifeline. But this wouldn't be readable. So a possibility would be having two instances of a threadclass in your class and show the interaction between the instances. But never show classes in a sequence diagram.
But why are you using a sequence diagram at all? For such internal behavour an activity diagram is most likely more appropriate. There you can use send and receive messages elements to express such a behavour per thread. Or if it shall be shown in one diagram, you can use fork.
How can I graphically represent within Statechart Diagrams that a state never gets executed more than a certain amount of times? So that it doesn't end in an infinite loop. Something like
assert enterPIN(int p) <= 3
and then branch to another state, if condition violated. Should I include it somehow in the guard? Or in the state activities?
EDIT:
(CheckPIN)--[invalid]-->(counter| + inc.)--[counter>3]-->(retainCard)
^ |
|-----[counter<=3]-----|
Something in this direction?
Legend: (StateName | (+-)activity), Transition: -->, [Guard]
I think your question is way too far down in the weeds. While you can model to infinitesimal detail, you should aim to create a much more durable model that will not require as much change over time.
H. S. Lahman makes an excellent case for using Moore state machines in his book, Model-Based Development: Applications. Moore state machines are where actions happen on entry to states, as opposed to where actions happen on transitions between states. His most compelling reason for using Moore state machines is that transitions do not degenerate into a sequence of function calls, they are instead announcements of things that have completed.
Here is an example of how to avoid all the detail and create a more durable model:
You'll notice that how things happen is completely encapsulated. For example, challenging the user might involve a PIN number, retina scan, or subdermal chip. The maximum failures allowed for each of those authentication modes might be completely different. That policy can be represented elsewhere.
To give a graphical answer:
This is how I would model it.
The counter object is usually not needed, since it's a simple counter and it's rather obvious that the rest/increment would refer to a common counter. Also there is no real <<flow>> to that counter. A not stereotyped dependency would also suffice.
I need to know this differences in order to undestand how to use them right.
Which are the differences of DFD and Activity diagram?
Actually, it's reasonably logical. You only have to look at the names.
In data flow diagrams, the lines between "boxes" represent data that flows between components of a system. Because these only show the flow of data, they do not give an indication of sequencing.
In activity diagrams, those lines are simply transitions between activities and do not represent data flow at all. They more represent the sequencing of activities and decisions. You can tell from these what order things happen in.
That's a simplistic explanation but should be a good starting point. Further information can be garnered from Wikipedia for DFDs and activity diagrams.
Explicit bias: I'm a DFDs proponent.
#John is correct that Activity diagrams can be used to represent object flow. #pax equally correct they seldom are.
Two big DFD advantages for me:
Link to object model. Data stores on a DFD provide a really nice way to link the data produced / consumed to the object model. Very useful for consistency and ensuring your thinking is joined up.
They de-emphasise control flow. Far too often designs over-constrain sequencing. Activity diagrams do support concurrency - but it requires the user to (a) remember and (b) use it. So the default is over-serialisation. DFDs don't. They lay bare the real sequence dependencies without any extra effort on the part of the user. Consequently they also make it easier to see causal relationships. If processes a and b both require data input D then it's obvious on the diagram. And hence parallel activity is obvious.
Don't get me wrong - I'm not against Activity diags. Where control flow is the primary consideration I'll use an AD over a DFD. But empirically I'd say I find DFDs a more useful tool in ~70-80% of cases.
Of course, YMMV.
Just a humble opinion from someone who has had to explain processes, both computer and manual, to upper management and CIOs. I have found simple is better and pound-for-pound, DFDs get the message across when I am actually "asked" about details. That being said, the better approach is to always practice the story line and answer in simple answers.
One final comment regarding the age of tools and products. Remember that in most cases these are running the business and work pretty darn good. The adage "you break it (or replace it) and you own it" can make you a hero or make you into a clown.
We have a CIO who wants to replace all mainframe application for the simple reason that they are old technology. One must weigh the consequences and understand if the replacement can handle workload. Have you ever wondered why JPMC, Credit Swiss, Walmart, and Bank of America to name a few still run mainframes?
My apologies for taking it in that direction. Just make sure, whatever analysis tool is used, that all aspects of the replacement are documented including workload, I/O, concurrent users, adoption curve, and scalability.
Data Flow represents flow within one module or one independent code. However Sequence Diagram represents sequence of activity in between different modules.
Yes at some points they may pass the same messages.
I basically use Sequence diagram in interface documents which will be shared with other modules/elements, however DFD will be used in Low level design documents which will be used to develop the code within one module or network element.
If we look closer to a dataflow diagram, we can notice that when a node collects data from all its edges, it starts to process them. And to process, it needs an activity token, which represents access to a processor. Usually the process of obtaining that token is omitted, but it has to exist. Typically, the whole node as a token is put in a double-ended queue, where on the other end of that queue free activities (processors or threads) are stored. A thread pool is a perfect example of such a queue, and the nodes ready to work are represented as tasks. As soon as a node meets activity, they both are taken from the queue and actual processing starts. When processing finishes, activity is returned to the queue. This way we can think of activity as a special kind of token.
So both dataflow and activity diagrams are just simplified variants of a general active-data-flow diagram, with either activities or data tokens omitted. But generally, both kinds of tokens can be represented in a diagram simultaneously.
Programmers used to think about threads as activities, but if we look at them closer, we notice that when a thread is ready to execute, it gets in a line to processors, and real execution starts only when a free processor switch to that thread. This is absolute analogy as tasks are executed on a thread pool. So from simplified point of view, a thread is an activity, and from more rigorous point of view a thread is a data token and the only real activity is a physical processor. This shows that activity tokens are not different from data tokens. And indeed, we can omit the route of node chasing an activity and consider a dataflow node as an activity itself, which starts to work immediately when all its edges (inputs) contain data.
I'm fond of using UML diagrams to describe my software. In the majority of cases the diagrams are for my own use and I use them for more involved pieces of code, interactions etc. where I'll benefit from being able to look back over them in the future.
One thing I've found myself doing a few different ways is diagramming threads. Threads by their nature tend to pop up in the more involved pieces of code and keeping track of them is often a primary purpose of my design documents.
In the past I've used a symbol in a sequence diagram to show the creation of a new thread but looking back at some diagrams doing that it's sometimes ambiguous between an object's lifetime - which sequence diagrams are for - and a thread's lifetime. Is there a better approach for incorporating threads into UML?
I managed to produce a diagram that makes sense to me at the time of drawing it. The basic premise is that I've overlaid grey boxes representing class instances with blue boxes representing thread lifetimes. The main thing it lets me keep track of is knowing which thread I will be executing on when I call certain methods.
No doubt there's better and more intuitive ways to do thread and class modeling. The measure of success for me is whether my own diagram still gives me the same level of understanding 6 months down the track.
Activity, Sequence, and State Diagrams are all correct ways of showing thread behavior.
1st: (To vs's comments) There are two sets of diagrams or modeling elements in UML, static structure, as you put it, and behavioral. Any book will help you understand the split, typically in the contents/TOC, additionally it can be seen on page 11 of Martin Fowler's UML Distilled a near defacto standard for beginning UML in my opinion.
2nd: (To sipwiz's question and comment) Activity diagrams are not commonly understood to model business process, they can be used for that however, and most examples or simple tutorial would approach it from a business standpoint.
Discussion on your options to model threads:
Activity diagrams - Allows for forking and specifying concurrency by using a BAR and usage lines. Note the example at the bottom is no a business process, example. Most people can read these, business, management, and developers, though sometimes they can lack detail or get messy.
Sequence Interaction diagrams - In the same post, example, you will see sequence diagrams allow you to specify parallel behavior within a sequence by boxing parallelizable behavior with a label "par", this is useful to show the reader what methods can or should be called in parallel, ie, by different threads. This is the method I would use for detailed developer like discussions around building an object.
State diagram - The state chart just like the activity allows for concurrency by using a BAR and usage lines.
NOTE: These will not model a specific thread and it's exact lift cycle, as that is part of the instance/run-time level of modeling, if this what you want clarify your question and I will respond. I would just model it using one of the above as no one other than a MDA/UML expert will call you out, and you are not generating a running system.
Also: Please note that further details can be found in most UML books.
Also leveraged: http://www.jguru.com/faq/view.jsp?EID=56322
Traditionally threading has been depicted diagramatically using Petri Nets. Rob Martin has an article on multithreading in UML which you may find useful.
Update- just remembered you can represent threads with forks in activity diagrams- I've managed to find something that explains this.
It is very hard to find any free tutorials for Petri Nets, however I know Petri Nets are good for modeling concurrency, so I Google'd "producer-consumer Petri Nets" (my favourite threading thing) and found this.
I've also found some slides that show Petri Nets modeling a Semaphore.
UML activity diagrams have fork and join elements to show parallel flow of logic.
I don't know of a way, but using a sequence diagram does not seem entirely inappropriate, considering that a thread is in many languages implemented as a Thread (or similar) class.
The most UML-compatible way would probably be to add an annotation of some sort indicating that the 'object' represents a thread.
The UML is defined by the UML Superstructure, you can find it here http://www.omg.org/spec/UML.
If you read the specification you find that a UML class can be active. An Active Class is a class with the meta-attribute isActive set to true. It is also depicted differently.
An object instances of an active class automatically executes a "classifier behavior". As for any behavior you can define it by means of an activity in which you wait for asynchronous signals (AcceptEventActions) and invokes methods (CallOperationAction) or other behaviors (CallBehaviorActions). That is how active objects are modeled in UML. You just have to read the UML specification.
Activity diagrams will model the internal workings of your software with forks and joins to represent threads. To find out exactly how to model this properly, please see Conrad Bock's excellent series of articles. Here is the article that covers forks and joins, but you should follow the links back to the first article in the series to learn how to properly model using "Colored Petri Nets". It's not how you think (and it's pretty easy)!
There is a new, in-process standard at the OMG for a language called Alf that provides a more convenient surface notation for activity diagrams and is intended for representing code. From the spec:
A primary goal of an action language is to act as the surface notation for specifying executable
behaviors within a wider model that is primarily represented using the usual graphical notations of
UML. For example, this might include methods on the operations of classes or transition effect
behaviors on state machines.
For a programmer, you probably can't get more intuitive than Alf. And it will convert perfectly into UML activity diagrams.
UML strongest point is depicting the static structure. If you use short-lived threads, I also don't see any easy way of diagramming them. Maybe you can find a solution by turning things around a bit: why do you use/need threads? What's the functionality they provide? If they interact with each other and follow some (message passing) API, drawing them as components might make sense.