Use Case Preconditions and Triggers
Some more notes, following a review of my team’s experience of writing a set of use cases during a recent round of development, this time looking at one of the areas my novice team struggled with, Use Case Preconditions and Triggers.
One of the problems with examples on line and in books is that they are always very clear cut. In practice, the real world often isn’t quite so neat. We had a lot of processes that were initiated as part of a batch process, and called each other, passing a record or parameters back and forth, causing a lot of discussion about how best to represent it. The informal use case description given as an example is similar to many of ours:
A billing process receives a customer transaction for charging. The system calculates the correct charge for each item by looking up tariffs that vary by customer and other factors. The system creates charge items (usually 3 or 4) for each transaction, and records that the transaction has been billed.
In trying to turn this into a more formal use case, we need some definitions:
The Trigger is the event that initiates the use case. It doesn’t actually have to happen, but it if does the use case steps will follow.
Preconditions are the things that are guaranteed to be true and the use case shouldn’t have to check them again (in fact, mustn’t).
In our example, what is the trigger? The business trigger is part of a wider batch process to charge all unprocessed transactions received since the previous run. It could be argued that the precise trigger is the calling process each time it identifies a new transaction for charging.
In our case, a Process New Transactions use case passes in data in a particular format, and we want to record that somewhere. Somehow it didn’t feel right hiding this information in the trigger, and we had a debate about the difference between the trigger and the first step. Cockburn’s view in Writing Effective Use Cases is that sometimes the trigger can also be the first step, sometimes it isn’t – but it isn’t possible to be completely consistent across the whole use case set, and not to worry about it too much.
We decided that we would state the trigger to be the batch process, and the precise call would be the first step in the main flow.
It is possible that this process could be called from multiple points in the system, not always passing in exactly the same parameters. In this case we decided to name all the calls in the trigger as alternatives to keep the first step brief.
Some of the team felt that the parameters passed in from the calling process formed a precondition, because the format of the input transaction had to be guaranteed – we didn’t want to have to validate it as our first step. It could be included as a formal precondition (“Transaction is valid”) but we didn’t see any value in that as we would have to state that in all similar use cases. In another situation it might be useful to state it explicitly (e.g. an interface to another system).
The other precondition that applies here is “Tariffs have been set up for each customer”. It is only necessary to declare preconditions that are specific to the use case, either those that are explicitly set up by the calling use case, or that are not considered by it but guaranteed elsewhere in the system. The other preconditions that might apply (e.g. “customer exists in system”) are inherited from the calling use case so didn’t need to be repeated. It is even possible that there are no preconditions at all.
How To Write Use Case Preconditions and Triggers by Scott Sehlhorst (Tyner Blain)