Новые требования сообщают две вещи:

  1. Уточнение того, что именно должен делать код. Эта информация показывает, каким образом должен был быть написан код.
  2. Повышение требований к изменяемости кода. После реализации нового требования код должен быть более приспособлен к такого рода изменениям, чем раньше. Приспособление кода к будущим изменениям такого рода осуществляется на основе OCP - принципа открытости/закрытости.

Если код, в который нужно добавить новую функциональность, не является “открытым для расширения”, нужно сначала провести рефакторинг, подготовив его к новой функциональности.

Общая схема такова:

  • Код “открыт для расширения”?
    • Если да, то добавить новый расширяющий код.
  • Понятно, как сделать код “открытым для расширения”?
    • Если да, то сделать код открытым, а потом добавить расширяющий код.
  • Рефакторить самый простой или самый понятный “запах кода”.

При этом нельзя смешивать процессы рефакторинга и добавления новых фич. Эффективная работа с унаследованным кодом#^code-change-reasons, #FeathersMichael уточняет, что это два очень разных процесса внесения изменений в код.

Своего рода метрики для следования принципу OCP приведены в
Архитектура ПО в Spring 5:

  • Какие изменения понадобится внести, чтобы добавить новую функциональность? В идеале модифицировать существующий код нужно очень незначительно. В основном новая функциональность должна быть сосредоточена в новых классах, реализующих существующие интерфейсы. Уточнения:
    • Нужно ли добавить новые операторы if? Нет (или один - в том месте, где проходит “шов” в терминологии #FeathersMichael ).
    • Как много существующего кода нужно изменить? Совсем чуть-чуть.
    • Насколько большими должны быть отдельные файлы исходников? Маленькими.
    • Нужно ли использовать абстракции? В пределах разумного. Интерфейс для единственной имплементации не нужен.