Для начала небольшое наблюдение. При прочих равных условиях маленькую программу создать обычно легче, чем большую. Однако так же верно, что суммарная сложность частей порой оказывается гораздо выше в собранной единой системе, чем в отдельных её составляющих. Иными словами по мере увеличения размера кода программы сложность создания растёт непропорционально применяемым усилиям.
После начала работ в случае линейной зависимости созданного функционала от затраченных усилий получаем прямую синюю линию. На практике же она часто становится красной линией, которая в конце концов может настолько сильно отдалиться от синей, что усилия на усовершенствование программы становятся неоправданно высоки. В идеале потратив время на создания гибкой архитектуры могли бы сократить издержки при расширении программы, в основном за счёт более быстрого комбинирования уже существующего функционала, смотрим зелёную линию.
Но архитектура это отдельный разговор, срабатывает лишь в определённых случаях. Пока же заострим внимание на схождении красной и синей линии, причём именно первая должна стремиться ко второй, а не наоборот. Речь об уменьшении возрастания сложности путём чёткого деления созданного функционала. Данная возможность базируется на
модифицируемости кода (Changeability QA) рассмотренного в предыдущей статье, то есть его способности к изменениям. Напомню, что речь о маркерах изменений позволяющих технично проводить операции над функционалом программы (выделить, вставить, удалить и обновить).
Хотя речь идёт о списке функционала, под этим часто подразумевают функциональные требования. Более того, нефункциональные требования не являются абстракциями, иначе программа без них была бы в точности идентична программе с ними. Так или иначе, но существуют куски кода явно или не столь явно их поддерживающие. Требования так же имеют
критерии качества (correct, unambiguous, complete, consistent, prioritized, testable, traceable, understandable, modifiable).
На изображении зелёным обозначен реализованный функционал, красным повторяющий уже существующий, а следовательно не требующий реализации, и синим планируемый для реализации в будущем. Как видно по маркерам изменений один функционал может быть вложен в другой, тоже самое касается и нового ещё не реализованного. Но важно не количество пересечений и взаимных вложений, важно точно отделять один функционал от другого.
Это необходимо для того, чтобы каждый раз:
1. решать маленькую задачу, а не большую
2. не анализировать аморфную массу кода с неясным предназначением
3. добавлять новые задачи не боясь повредить программу
Используя подобную технику программирования при решении маленькой задачи все остальные должны игнорироваться на уровне сознания. Исходить нужно из преследуемой цели, и в то же время жёстко отсекать её от остальных. В коде необходимо обязательно установить маркеры изменений в каком-либо виде для определения границ ответственности, а так же прослеживании связей с функционалом.
Напоследок хотелось бы отметить изначальность происхождения явлений в программировании. Это касается образцов проектирования или какого-нибудь трекера задач (планирование, бизнес-модель, требование, проектирование, конструирование, испытание, ошибка, документирование, развёртывание, сопровождение). Нужно помнить, что в конечном счёте все систематизированные знания приходят к нам из кода, и код это единственный конечный продукт результата программирования.
Проблемы начинаются тогда, когда рафинированную информацию начинают отдавать в отрыве от кода, и остаётся смутная догадка для чего это использовать, но абсолютно нет понимания как применить подобное на практике. В мире огромное количество разнообразных методологий программирования, каждая из которых представляет собой продольный или поперечный срез другим. И даже самый популярный язык программирования всего лишь чья-то выдумка.