Этап программного синтеза
sergey shishkin- Переход на взаимодействие со сложными рукотворными исполнителями
- Копирование алгоритма от человека к компьютеру — это обучение последовательности действий (программирование) + обучение признакам, требуемым для контроля выполнения (например, Machine learning)
- Переход от свободы формирования кода к ограничениям, способствующим расширения возможности развития и сопровождения программного проекта, как алгоритмической системы с подходом сходным, но и отличающимся от биологического способа развития организма.
Программа — это кодовая структура алгоритма, которая способна осуществить исполнение этого алгоритма в среде не являющейся организмом () ...
- Сходство и отличие эволюций организма и программы;
- Простота копирования и переноса блоков кода (stackoverflow);
- Использование трансляции модели для формирования кода
- Целесообразны малые изменения — эволюция алгоритма, и соответствующие приемы обособления (микро-commit-ы);
- Целесообразно разделение на блоки меньшей сложности;
- Доступен трансфер изменений между сходными проектами (в отличие от природных возможностей развития организма);
- Вставить статью "ООП" и обособить общие законы изменения программы;
- Использование ограничения свободы изменения пользовательского интерфейса в оконной системе;
- Эффективные ограничения языка программирования;
- Преобразовать стиль статьи
В текущее время существует множество подходов для проектирования и последующей реализации программных проектов. Наиболее востребованными в работе с большими программными проектами являются:
- структурное программирование,
- функциональное программирование,
- объектно-ориентированное программирование.
Краткий обзор технологий развития кода
- структурное программирование
- функциональное программирование
- ООП
- шаблоны проектирования
- SOLID принципы
- контроль изменений и версии кода
Интересен анализ причин возникновения этих подходов проектирования. Все они неявно основываются на следующей предпосылке:
Необходимость планомерного развития проекта с минимизацией затрат на повторное написание кода, тождественного или сходного с уже существующим.
Существует ли программный проект без необходимости развития? Да, такие проекты изредка встречаются и в основном характеризуются быстрой сдельной оплатой без возникновения последующих обязательств со стороны программиста, например:
- небольшой проект, который возможно написать с одного подхода;
- проект без структурно-сложного кода, обремененного большим количеством взаимосвязей;
- программный продукт без необходимости его сопровождения и поддержки пользователей.
В подобных ситуациях усилия программиста, направленные на поддержание системы развития программного проекта, например, объектно-ориентированного подхода, тратятся впустую.
Во всех остальных ситуациях программист, минимизируя свой труд, должен развивать структурно-сложный проект, то есть:
- Производить корректировку ошибок, анализируя код и находя места, в которых эти ошибки формируются.
- Вносить новые функциональные возможности, сохраняя при этом работоспособность всех ранее имевшихся возможностей. При этом использовать уже существующий код (написанный и проверенный) в реализации этих новых задач.
- Обеспечивать поддержку в использовании программного продукта.
- Выполнять описание и согласование функциональных возможностей всех версий проекта.
- Сохранять работоспособными все, используемые проектом форматы данных (даже устаревшие).
- И выполнять многие другие задачи, появляющиеся в противостоянии с конкурентами, вызванные изменяющимися фреймворками или завершением поддержки устаревших ОС...
Если поискать аналогии развитию программного проекта, то можно вспомнить эволюцию биологического вида.
Программный проект подобен сложному развивающемуся "организму". Программист для этого организма — изменчивость и естественный отбор в одном лице. Зарплата программиста совместно с его навыками — скорость эволюции.
Труд программиста не легок. Но у программиста есть помощник. Этот помощник спрятан где-то глубоко в устройстве нашего мира, в котором есть две особенности:
- возможность написать один алгоритм и использовать его для множества сходных задач,
- наличие превеликого множества задач сходных по своему решению.
Этот используемый во многих областях алгоритм является ничем иным как универсальным алгоритмом. Его реализация для конкретной прикладной области будет специализацией. В этом процессе подобие с эволюционной специализацией клеток в живом организме. Очевидно, что для создания универсального алгоритма требуется выделить признаки, которые обеспечивают применимость алгоритма. Эти признаки необходимо искать во входных данных и в описании начальной ситуации (контекста). Для создания универсального алгоритма необходимо в каждой прикладной области, имеющей свои наборы признаков данных и ситуаций, выделить тождественные для всех областей признаки применимости. Все остальные признаки, не обеспечивающие применимость, универсальным алгоритмом игнорируются.
Используя разные приемы выделения абстракций и использования трансляции, программист выполняет реализацию алгоритма в виде "участка кода", который представляет собой обособленный и законченный элемент его труда. Этот элемент в зависимости от используемого языка программирования может представлять собой и функцию, и объект, и последовательность инструкций. Назовем для удобства дальнейшего изложения этот "кирпичик программного строительства": блок кода.
Блок кода — кодовый алгоритмический блок (участок кода, процедура, класс, компонент, пакет, библиотека...)
- который обеспечивает опору некоторому законченному алгоритму, работающему в определенных начальных ситуациях и с определенными входными данными,
- который возможно использовать несколько раз в одном проекте (еще лучше много раз в разных проектах),
- все инструкции которого расположены близко и просматриваются без необходимости дополнительных поисковых операций в среде разработки,
- изменения в котором программист выполняет относительно независимо по отношению к остальным участкам кода.
С использованием термина блок кода появляется возможность сформулировать совокупность простых закономерностей, существующих в разработке программного проекта. Эти закономерности представлю в виде следующих утверждений, разбитых на 3 категории.
- ⟨1⟩ Утверждения, описывающие свойства блока кода.
- ⟨1.1⟩ Корректно написанный блок кода обязательно используется и чаще несколько раз.
- ⟨1.2⟩ В каждом месте использования блока кода от него ожидается неизменное поведение, приводящее к повторяемому результату.
- ⟨1.3⟩ При использовании блока кода в нескольких местах результат должен удовлетворять каждому месту использования.
- ⟨1.4⟩ Поведение, заложенное в блоке кода, формирует ограничения для мест использования этого блока кода.
- ⟨1.5⟩ В каждом месте использования блока кода могут быть задействованы все его ограничения.
- ⟨1.6⟩ Любое изменение блока кода изменяет его ограничения и требует проверки всех мест его использования, что порождает затраты времени программиста.
- ⟨1.7⟩ Блок кода целесообразно записывать в виде кода в одном экземпляре, то есть необходимо устранять дублирование одинакового кода. Это уменьшит количество правок при внесении изменения в блок кода.
- ⟨2⟩ Утверждения, описывающие закономерности в реализации программистом новой задачи.
- ⟨2.1⟩ Вариант реализации новой задачи целесообразно выбирать минимизируя затраты времени программиста.
- ⟨2.2⟩ Для реализации новой задачи программист может добавить новые блоки кода или изменить поведения старых блоков кода.
- ⟨2.3⟩ Добавление блока кода в основном требует проверки только в месте нового использования, и порождает минимальные затраты времени программиста.
- ⟨2.4⟩ Обусловленное новой задачей изменение поведения блока кода, согласно ⟨1.6⟩, требует проверки в месте нового использования и во всех местах старого использования, что порождает дополнительные затраты времени программиста по сравнению с ситуацией в утверждении ⟨2.3⟩. В случае опубликованного блока кода это требует работы всех программистов, использовавших измененный блок кода.
- ⟨3⟩ Утверждения, описывающие закономерности во взаимодействии универсальных алгоритмов и их специализаций:
- ⟨3.1⟩ Существует возможность написать базовый блок кода (название вводится по аналогии с базовым классом и далее для краткости будем использовать слово: база). База набором интерфейсных алгоритмов своего блока кода обеспечивает главные признаки некоторого универсального алгоритма.
- ⟨3.2⟩ Существует возможность написать блока кода, являющегося реализацией базы. Реализация дополняет интерфейсные алгоритмы базы, делая универсальный алгоритм на основе этой базы применимым в конкретной прикладной области.
- ⟨3.3⟩ База, как следует из утверждений ⟨3.1⟩, ⟨3.2⟩ имеет меньшую сложность и меньше ограничений в применении, чем реализация.
- ⟨3.4⟩ Согласно утверждению <1.7>\left<1.7\right>⟨1.7⟩ реализацию целесообразно разрабатывать без дублирования кода интерфейсных алгоритмов базы.
- ⟨3.5⟩ Места использования базы в универсальном алгоритме не требуют проверки после внесения изменений в корректно сформированную реализацию.