Being the same doWork task, you can probably define a linked list or jobs vector and pass this as a doWork parameter, add the corresponding information to this list inside the function and only call undoWork once:
If(doWork("A", &jobs)<0){ return -1; } If(doWork("B", &jobs)<0){ undoWork(jobs); return -1; } If(doWork("C", &jobs)<0){ undoWork(jobs); return -1; } return 0;
Thus, your logic will not become overly complex, no matter which combination of tasks is canceled.
The advantage over the @ twain249 solution is that the function decides whether the task is added to the list or not, so you have good isolation, modularity.
Of course, you can combine some form of interdependent data structure with this to further reduce the amount of duplicate code :
for(i=0; i < jobdata.size; i++) { If(doWork(jobdata[i], &jobs)<0){ undowork(jobs); return -1; } }
As you can see, the structure of the data structure plays an important role in the development of algorithms, usually much more important than usually thinks.
There may be thousands of tasks, the code will remain four-line.
Flavius
source share