Like most behavioral modeling techniques, activity diagrams have definite strengths and weaknesses, so they are best used in combination with other techniques.
The great strength of activity diagrams lies in the fact that they support and encourage parallel behavior. This makes them a great tool for workflow modeling and, in principle, for multithreaded programming. Their great disadvantage is that they do not make the links among actions and objects very clear.
You can define a link to an object by labeling an activity with an object name or by using swimlanes, which divide an activity diagram based on responsibilities, but this does not have the simple immediacy of interaction diagrams (see Chapter 5). For this reason, some people feel that using activity diagrams is not object-oriented and, thus, bad. I've found that the technique can be very useful, and I don't throw useful tools out of my toolkit.
I like to use activity diagrams in the following situations:
Analyzing a use case.
At this stage, I'm not interested in allocating actions to objects; I just need to understand what actions need to take place and what the behavioral dependencies are. I allocate methods to objects later and show those allocations with an interaction diagram.
Even before I get into use cases, I find activity diagrams very useful for understanding a business process. I can easily draw these diagrams together with business experts to understand how a business operates and how it may change.
Describing a complicated sequential algorithm.
In this case, an activity diagram is really nothing more than a UML-compliant flowchart. The usual pros and cons of flowcharts apply.
Dealing with multithreaded applications.
I have not personally used activity diagrams for this purpose, but I have heard some good reports.
Don't use activity diagrams in the following situations:
Trying to see how objects collaborate.
An interaction diagram is simpler and gives you a clearer picture of collaborations.
Trying to see how an object behaves over its lifetime.
Use a state diagram (see Chapter 8) for that.
Representing complex conditional logic.
Use a truth table.
The work on UML 1.3 added a lot more rigor and precision to activity diagrams. However, that's a mixed blessing. The problem is that when you use these diagrams for conceptual modeling, much of this rigor gets in the way. In these situations, you aren't aiming for complete accuracy, just a general overview of how things work. In any case, you're unlikely to get it right, even if you try, unless you're able to execute and test the diagram. Remember Bertrand Meyer's phrase: "Bubbles don't crash."
On the other hand, by having a standard for state and activity diagrams, there's a more stable foundation for tool developers to build tools that will execute these diagrams. Such tools will allow you to run and test these diagrams.