The answer depends hugely on what language you're using and what you are going to do as a consequence of the errors.
For example, in Scala, and assuming that I want to report every error so that they can all be fixed at once, I'd probably do something like
val (yes, no) = List( (A, "A failed"), (B, "B failed"), (C, "C failed"), (D, "D failed") ).partition(_._1) if (!no.isEmpty) Some(no.map(_._2)) else None val (yes, no) = List( (A, "A failed"), (B, "B failed"), (C, "C failed"), (D, "D failed") ).partition(_._1) if (!no.isEmpty) Some(no.map(_._2)) else None where I first group my conditions and error messages, then sort them into two groups--the successes and the failures--and return those error messages if there was something, and otherwise return a sentinel value saying--in this case--that everything's okay.
But this relies critically on Scala's ability to quickly group and map and manipulate collections and containers. In Java, I would write the exact same code in the more verbose (and less convenient to check, as I now need to query errors.size() to know whether I have failed anything):
ArrayList<String> errors = new ArrayList<String>(); if (!A) errors.add("A failed"); if (!B) errors.add("B failed"); if (!C) errors.add("C failed"); if (!D) errors.add("D failed"); return errors; ArrayList<String> errors = new ArrayList<String>(); if (!A) errors.add("A failed"); if (!B) errors.add("B failed"); if (!C) errors.add("C failed"); if (!D) errors.add("D failed"); return errors; If we only need the first error, in Java I'd do fail-fast while in Scala I might
List(A,B,C,D).zipWithIndex.find(!_._1).foreach{ x => return x._2 } List(A,B,C,D).zipWithIndex.find(!_._1).foreach{ x => return x._2 } assuming I was okay with the number of the item that went bad as a return code.
So the answer is really: you've got the important different styles, but how exactly to implement them most efficiently/least painfully is going to depend a lot on your tools.