Separation of concerns is at the core of software engineering in general, and of object-oriented software development in particular. Done well, it can provide a host of crucial benefits: additive, rather than invasive, change; improved comprehension and reduction of complexity; adaptability, customizability, and reuse, particularly of off-the-shelf components; simplified component integration; and the ultimate goal of “faster, safer, cheaper, better” software.
To benefit fully from separation of concerns, one must have the right modularization at the right time; the concerns that are separated must match the concerns one needs to deal with. Unfortunately, different development activities often involve concerns of dramatically different kinds. For example, changing a data representation in an object-oriented system might involve a single class, or a few closely-related classes, and might be done additively using subclassing or suitable design patterns. Here the hallmark of object orientation – modularization (or object) – is a major asset. On the other hand, adding a new feature to a system typically involves invasive changes to many classes: the feature code is scattered across multiple classes; and tangled with other code within those classes. This reduces comprehensibility and increases impact of change and the likelihood of error. In short, one needs different modularizations for different purposes: sometimes by feature, sometimes by aspect (e.g., distribution or persistence), role, variant or other criterion.