Software Design/Split responsibilities between classes and functions
Checklist questions:
- Does a class have a single responsibility?
- A business logic area
- An external integration (database, service, API)
- A domain data object, a builder, or a configuration class for another class
- An aspect of the program's control flow or data flow, such as an active object, or an object integrating other objects
- Does a function have a single responsiblity?
- A single business logic operation
- A single kind of external operation (e. g. a specific API call or a database operation)
- An aspect of program's control flow, or a function integration other functions (including higher-order functions)
- If a function has more than three (3) parameters, couldn't its responsibilities be split between multiple functions?
This practice corresponds to the Single Responsibility Principle, applied on the level of classes.
Why
edit- Steepness of learning curve: less cognitive load when learning the code, the learning process is more manageable
- Easiness of future change: replace classes and functions, combine them in different ways
- Reusability: more likely that focused classes and functions could be reused in several places in the codebase, fostering DRY
- Testability: unit-testing of small classes and functions doesn't require mocking or fragile control of side effects
- Debuggability: debugging is not needed or quicker when a focused unit test fails
- Observability: in profiling results, the bottleneck could be identified more clearly. Sizes of queues between classes organized in a SEDA-like pipeline could be monitored.
- Software Design/Structuredness: when followed consistently, Single Responsibility Principle is itself a form of structure
Why not
edit- Splitting responsibilities results in more code, classes, and functions
- More navigation between classes and functions is required
- Resource usage and performance: more classes and functions need to be compiled and/or loaded by the runtime. More calls and more code mean less effective usage of the instruction cache.
Related
edit- Extract Class refactoring
- Extract loosely coupled parts of a class into smaller classes
- Break up too large and complex functions
- Extract self-contained pieces of logic as functions
- Keep the number of function arguments low entry in C++ Core Guidelines suggests that a function having too many parameters is a hint that it may have multiple responsibilities.