One reason why "ifs are smelly" has become a maxim in some circles is because they represent an under-tested code path. In such areas as safety-critical/life systems, where a different codepath can be taken on the basis of a single var, this can be a very, very dangerous practice. Certainly in safety-critical, a reduction of "if"-based codepaths represents <i>higher quality software</i> in the end.<p>I have seen cases of radiation-derived bit-rot which don't manifest in any way until a certain "if"-path is evaluated by the computer - this seriously does happen and can still happen in modern computers today.<p>Having an abundance of such code switch points in a particularly large codebase can be a degree of complexity that nobody really wants to manage - or in the case of disaster, be responsible for .. so this maxim has been pretty solidly presented in industrial computing for a while. Make the decision-making as minimal as possible to get the job done, and don't over-rely on the ability of the computer to evaluate the expression in order to build robust software.<p>Now, its sort of amusing that this has propagated into the higher-order realms of general application development by which most Class/Object-oriented developers are employed .. but it is still an equally valid position to take. State changes in an application can be implemented in a number of different ways, "if" being one of the more banal mechanisms - there are of course other mechanisms as well (duffs devices, etc.) which are equally testable, yet more robust - simply because they break sooner, and can thus be tested better.<p>I take the position, however, that a well-designed class hierarchy won't need much navel-gazing decision-making, which is what the ol' "if (something == SOMETYPE)" statement really is: a kind of internal house-keeping mechanism being done by the computer at runtime, instead of at compile-time.<p>So there is a balance to this maxim, and the key to it is this: how complex does it need to be, versus how complex can the codebase be before it becomes unmanageable. If you're not doing full code-coverage testing with 100% testing of potential codepaths, then every single if statement represents a potential bug you didn't catch yet.