|
© 2025
Александр Легалов
Примеры программ (151 кб)
Содержание
Очередная глупость?
|
|
Надо ж выдумать такое - во дурак!
Король и Шут. "ДУРАК И МОЛНИЯ"
|
При разработке программ используются разнообразные, но достаточно простые технические приемы, которые в совокупности обеспечивают поддержку требуемых критериев качества. Ряд таких приемов направлен на достижение гибкости и эволюционной расширяемости программ. Применяемая в таких ситуациях техника в основном проработана для объектно-ориентированной (ОО) парадигмы программирования и отражена в соответствующих рекомендациях. К известным приемам написания хорошего кода можно отнести паттерны проектирования, принципы SOLID и другие. Их применение наслаивается на конструкции, определяемые предметной областью, обеспечивая при этом более гибкое развитие программы за счет использования динамического полиморфизма. Альтернативой, также обеспечивающей гибкое кодирование, являются другие техники и парадигмы. Они также поддерживают динамический полиморфизм, но при этом в концептуальном плане пока менее, чем объектно-ориентированное программирование (ООП) проработаны для использования в рамках больших проектов.
Формирование сложных конструкций осуществляется на основе базовых техник, предлагаемых той или иной парадигмой программирования. Именно на этом уровне выявляются ограничения, достоинства и недостатки разных подходов. В больших программных системах эти ограничения зачастую приходится преодолевать за счет применения различных трюков и выработанных рекомендаций (паттерны, SOLID...), которые зачастую искажают непосредственное восприятие предметной области. И происходит это из-за необходимости достижения соответствующих критериев качества.
Мы неоднократно рассматривали варианты эволюции и сравнивали возможности процедурно-параметрической парадигмы программирования (4П) с другими парадигмами. Ряд результатов представлены с соответствующих публикациях [4ПНаши публикации по процедурно-параметрической парадигме программирования]. Однако в настоящий момент хотелось бы сопоставить возможности, которые предоставляет процедурно-параметрическое программирование (ППП) в сравнении с другими подходами для простых ситуации, определяющих расширение программ. Ниже эти простые ситуации рассмотрены для процедурного, объектно-ориентированного и процедурно-параметрического (ПП) подходов. В тех или иных комбинациях они уже неоднократно рассматривались, но хотелось бы продемонстрировать их с описанием кода, рисунками и несколько ином варианте формирования расширений. Показать, что ППП круче, чем ООП (в этом и заключается возможная очередная глупость).
Маленький демонстрационный пример
|
|
"Это один маленький шаг для человека, но гигантский скачок для всего человечества."
Нил Армстронг
|
По сложившейся традиции я использую те же примеры с геометрическими фигурами, которые были описаны в различных статьях, а также представлены в репозитории демонстрационных ПП программ. Код, используемый в этом материале, тоже размещен в одном из каталогов репозитория. Сверху на странице есть также ссылка на архив исходных текстов. Основной особенностью рассматриваемых ниже примеров, по сравнению с аналогичными решениями, является то, что они сформированы с использованием несколько иного принципа. Если в предыдущих ситуациях, программа, расширяемая по сравнению с предыдущим шагом, использовала неизменяемые копии ранее созданных исходных текстов, то в новых примерах наследуемые исходники не копируются, а подключаются из предыдущих проектов. Это позволяет избавиться от дублирования неизменяемого кода и более наглядно посмотреть, что нужно добавить или модифицировать при расширении программы в том или ином направлении.
Реализованы восемь ситуаций, которые определяют различные варианты эволюционного расширения. Почти все они стартуют от первоначального решения, в котором осуществляется ввод параметров используемых геометрических фигур различного типа из файла в контейнер обобщенных фигур, представленный простым одномерным массивом (идентичным для всех рассмотренных парадигм). После этого осуществляется вывод из контейнера в другой файл. Варианты решений реализованы с использованием процедурного программирования на языке C, ОО программирования на языке C++ и процедурно-параметрического программирования на языке PPC. Управление всеми проектами реализовано с использованием CMake. Есть скрипты, которые для каждой из парадигм формируют исполняемые файлы. В качестве допущения для всех подходов в основном рассматривается реализация только прямых решений. То есть, не используются различные дополнительные косвенные связывания и трюки, которые позволяют построить более гибкий код. Еще, как и ранее отмечу, что гибкую эволюционно расширяемую программу можно на данных языках построить без особых проблем. Но для этого требуется использовать дополнительные конструкции, напрямую не связанные с решаемой задачей.
Языки Go, Rust и другие здесь не рассматриваются, так как у меня вызывает сомнения что для их модульной структуры можно реализовать использование исходников из разных программ в разных проектах. Но здесь я могу ошибаться из-за отсутствия более глубоких знаний. Все-таки, это не мои языки. Но буду признателен, если кто-то вдруг и где-то представит соответствующие альтернативные варианты.
Ниже приведены ситуации эволюционного расширения программы, реализованные для описанных парадигм и языков.
Исходная программа реализующая ввод в обобщенный контейнер и вывод из него прямоугольников и треугольников.
Добавление в первую программу круга в качестве еще одной альтернативы.
Добавление в первую программу обобщенной функции, осуществляющей вычисление периметра для каждой из альтернатив: прямоугольника и треугольника. Вывод периметров для всех фигур, размещенных в контейнере.
Добавление в первую программу общего поля данных, задающего цвет для каждой из фигур, расположенной в контейнере.
Добавление в первую программу возможностей вывода из контейнера только фигур одного типа. В данном случае только прямоугольников.
Добавление в первую программу мультиметода.
Расширение мультиметода из шестой программы за счет добавления круга из второй программы.
Формирование нового обобщения, использующее данные из уже сформированных специализаций исходного обобщения первой программы.
Перефразируя Армстронга. Предполагается, что на примере этих маленьких программ удастся показать варианты прямого использования разновидностей динамического полиморфизма в гигантских проектах.
Содержание
|