Flexibility is software’s capacity to adapt to related tasks and changing requirements. Flexible code resists change less: implementations can be swapped, behaviors can be extended, and modifications stay localized. Designing for flexibility involves trade-offs, so improvements should serve realistic future needs rather than add complexity without purpose. section 1.4.1 section 7.1.2
Recognize flexibility through these practical signals:
- Separate responsibilities so code can be generalized for several use cases or extended with more varied behavior. section 6.2.1
- Prefer adding new behavior without disturbing existing code, while accepting that real systems sometimes require careful modifications. section 7.1.1
- Reduce resistance before making a change through decomposition, encapsulation, and small continuous refactorings. section 7.1.2
- Avoid premature abstractions: temporary duplication can be safer than an abstraction based on incomplete knowledge of future uses. section 7.1.1
Replace rigid conditionals with a mapping
A long chain of if/elif statements repeats the structure of each choice and makes changes harder to locate. A dictionary centralizes the mapping: choices = {'A': 'apples', 'B': 'bats', ...}; print(f'{choice} is for {choices[choice]}'). Adding or changing an outcome then focuses on the mapping instead of another conditional branch. section 7.1.2
Use the diagram to relate reusable core business logic to multiple use cases, such as a command-line interface and a mobile application. section 10.4








