Being the same task doWork
, you can probably define a linked list or vector of jobs
and pass that as a parameter to doWork
, append 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;
This way, your logic will not become overly complicated, no matter the combination of jobs to be undone.
The advantage, compared to @twain249's solution, is that the function decides whether a job is added to the list or not, so you've got a nice isolation, modularity.
You can of course combine some form of an interable data structure with this, to further reduce the amount of repetitive code:
for(i=0; i < jobdata.size; i++) {
If(doWork(jobdata[i], &jobs)<0){
undowork(jobs);
return -1;
}
}
As you can notice, data structure design plays an important role in algorithm design, usually a much more important one than one usually thinks.
There could be thousands of jobs, the code will remain a four-liner.