
« Безумству храбрых поем мы песню»
Привет, Хабр! Меня зовут Евгений, я ведущий разработчик отдела SAP разработки.
Большинству из нас рано или поздно приходится сталкиваться с задачами оптимизации ПО. Последние пару лет мне пришлось плотно поработать в этом направлении, и в итоге решил поделиться некоторыми своими наблюдениями\выводами.
Статья описывает общий подход к увеличению производительности ПО. Для новичков в подобном "развлечении", она позволит понять что делать и куда смотреть в первую очередь. Опытные разработчики, надеюсь найдут для себя что то полезное, или смогут упорядочить свои знания.
Первоначально задумывалось, что целевая аудитория — SAP ABAP разработчики и ТехЛиды. Однако, после того как была написана основная часть статьи, пришло понимание, что рассказать все в одной публикации не получится, а специфика SAP систем фактически остается за кадром. Поэтому, к.м.к. получившийся вводный материал будет полезен разработчикам независимо от специализации, и возможно консультантам\системным аналитикам.
Оглавление
1. Постановка задачи
Что такое производительность?
Да, а что такое производительность? Термины же важны, и не важны одновременно.
Можно взять какое‑нибудь из определений производительности ПО, например:
Способность системы выполнять заложенные в нее функции для заданных ограничений по времени обработки и пропускной способности.
Способность приложения или системы эффективно выполнять поставленные задачи, обеспечивая высокую скорость работы и минимальное потребление системных ресурсов
А можно вспомнить какой‑нибудь случай, когда к вам приходят со словами:
«Ваша программа работает уже 12 часов, а должна была отработать за три! Что за... безобразие?».
«Почему я перехожу на страницу сайта и успеваю выспаться пока браузер ее отрисует?»
«Опять ваше... изделие съело всю доступную память сервера и упало в дамп!»
Все эти формулировки в свободной форме сводятся к двум основным претензиям:
Программа работает слишком медленно. Что бы это не означало в конкретном контексте.
Программа потребляет слишком много ресурсов. Память, диски, сеть... нужное подчеркнуть.
А это правда важно?
Скажем правду, в большинстве случаев производительность не имеет значения.
Есть много других проблем, более актуальных на момент создания ПО.
Например: Cможем ли мы закончить эту разработку в приемлемые сроки? А когда закончим, будет ли хоть кто-нибудь ей пользоваться? Нам заплатят за нашу работу...? Почему, почему они опять хотят все изменить? :)
Ну и прочие радости из жизни разработки софта.
Однако, для определенных случаев, и для некоторых классов систем производительность важна.
Когда повезет, на это обращают внимание уже на этапе постановки задачи, и производительность системы становится одним из важных архитектурных критериев.
Тогда уже на этапе разработки архитектуры и проектирования системы закладываются решения позволяющие достичь требуемых характеристик производительности, надежности и т.д.
Но мы же знаем, как это происходит в real life. О простите, в реальной жизни :)
В лучшем случае, проблемы производительности решаются в момент их возникновения на этапе разработки или тестирования. И в целом это неплохо, потому что во время разработки\приемки значительно проще изменить реализацию. Конечно это сильно дороже, чем если бы мы подумали заранее. Но все же, это сильно проще и дешевле чем делать доработку решения уже ушедшего в промышленную эксплуатацию.
Ну и наконец самый распространенный вариант.
Система\программа\комплекс ПО разработан, прошел приемочные испытания, был успешно сдан в опытную, а затем промышленную эксплуатацию.
После этого в течение N лет дорабатывался\изменялся\модернизировался, обрастал дополнительным функционалом и в итоге пришел к состоянию - оно как то работает. Работает, решает проблемы бизнеса, но скорость перестала удовлетворять пользователей, а потребление ресурсов - постоянная головная боль для службы ИТ.
В этом момент возникает задача оптимизации работы программы. Вспоминают что производительность это одно из архитектурных требований, оно важно, и .. надо что то делать.
А дальше приходят к разработке со словами "сделайте красиво." И нет, переписать все, слишком дорого, долго и вообще, уже никто не понимает полностью, как оно работает.
Тут мне всегда вспоминается очень старый анекдот:
"Одна американская фирма купила дорогое японское оборудование по производству ( чего-то ). Его установили, настроили и оно начало беспрерывно работать, принося солидную прибыль. Дела у фирмы пошли резко в гору и всё было хорошо. Но однажды станок сломался и остановился. Все попытки отремонтировать его были безуспешны.
Тогда директор фирмы объявил, что тот, кто запустит станок получит 1000 долларов.
Много лучших умов и рук трудились, но у них ничего не выходило.
И тут пришёл простой слесарь из цеха, походил, посмотрел, взял кувалду и ударил ей станок. Всё заработало как раньше.
Вызвал рабочего довольный директор к себе и сказал, чтобы тот написал отчёт о выполненной работе для получения обещанной премии.
Рабочий написал: 1 доллар за то, что ударил кувалдой и 999 долларов за то, что знал куда бить."
Ну и зачем все "эти много букв"? Что сказать то хотел?
В этом случае разработчик оказывается в ситуации слесаря из анекдота выше по тексту.
Есть сложная штука, которую нужно починить одним "ударом молотка"- ограниченным "точечным" воздействием, т.е. рефакторингом как можно меньшей части уже существующего кода\приложения.
Вот о том, как можно подходить к оптимизации в такой ситуации я и хотел поговорить.
Подход к оптимизации ПО одинаковый или очень похожий для многих распространенных приложений. Да и в целом для многих процессов, включая организационные.
В этот момент принято вспоминать о теории очередей, пропускной способности, утилизации ресурсов, времени обслуживания, управляемой деградации, моделировании высоконагруженных систем и прочих, местами интересных а местами не очень, понятиях.
Все они конечно важны, и как мы знаем, "нет ничего практичнее хорошей теории", но в рамках статьи постараемся их по возможности не использовать.
Будем работать в любимом мной формате - шпаргалка краткая для практика, с ссылками на литературу для углубленного изучения.
И да, рассматривать всe будем на примере SAP S4HANA.
Общий подход к оптимизации ПО
Итак, на входе у нас незнакомая программа, и требование "сделать красиво" ускорив ее выполнение в N раз.
С чего начать?
Шутишь, начинать нужно всегда с начала.
2. Определить цель оптимизации производительности
Фундамент успеха закладывается на первом шаге. А именно, нужно понять в чем наша цель. Что именно мы оптимизируем? Не с точки зрения техники, а с точки зрения бизнеса.
Оптимизация ради оптимизации - кредо неудачника :) Ну или технического эксперта стремящегося к совершенству. К сожалению, а может и к счастью, чистое искусство в коммерческих проектах не оплачивается.
Требования к производительности:
Должны опираться на конкретные бизнес показатели Что конкретно не так? Система не может выполнить нужно количество операций в единицу времени? Например, фоновое задание должно обработать 1 млн. заказов ночью за 3 часа и обязательно успеть к 7 ч утра. Или отклик на нажатие кнопки не должен превышать 0.5 сек, иначе покупатели прерывают оформление покупки на кассе самообслуживания.
Находится в приемлемом диапазоне. Не слишком высокие (будут большие затраты на достижения требуемой производительности ) и не слишком низкие (будет просадка по бизнес показателям ). Часто требования необоснованно завышают, а потом удивляются, почему доработка обходится так дорого. Принцип Парето 80\20 и Баланс это слова которые вам придется прочувствовать на своей шкуре.
Крайне важно получить от бизнеса\постановщика задачи необходимую пропускную способность (количество одновременно работающих пользователей\кол-во транзакции в секунду\кол-во отчетов). Где высокие нагрузки, там и высокая параллельность. Было бы странно оптимизировать отчет под один запуск\одного пользователя, а потом удивляться, что запуск двух-трех одновременно убил систему. Такое тоже бывает.
Часто встречающиеся способы сформулировать требования к производительности:
▪ Время отклика (response time);
▪ Количество операций в единицу времени (throughput);
▪ Количество обрабатываемых данных в единицу времени (throughput);
▪ Ограничения на утилизацию ресурсов (utilization);
▪ Количество одновременно работающих пользователей системы.
Будем считать что мы поняли какова наша цель - определили критический параметр, четко\измеримо сформулировали задачу и что немаловажно, зафиксировали ее в письменном виде. Не проговорив ртом, а написав буквами. Например в виде ТЗ, ФС или просто в email с подтверждением от постановщика задачи.
3. Получить эталонные тестовые случаи
На этой стадии мы понимаем что мы хотим достичь, но не понимаем где находимся. Поэтому обязательный шаг перед началом каких либо изменений в уже существующем решении\программе - замер параметров производительности.
А для этого нужно определиться как мы будем проводить замер и на каких примерах.
В этой точке нужно вспомнить про Критичные сценарии использования и связь с ними параметров производительности.
Попытаемся сформулировать что нам нужно от тестового сценария:
▪ Для проверки выполнения требований по производительности тестовый сценарий
должен быть верифицирован\согласован.
▪ Тестовый сценарий должен описывать точки измерения выбранного параметра производительности ( например времени выполнения определенных операций )
▪ Для нагрузочного моделирования необходимо разработать типовые модели
нагрузки. ( Один пользователь выполнил одну операцию. Один пользователь массово выполнил N операций. X пользователей выполнили N операции, и т.д )
▪ Определить последовательность действий в рамках каждого сценария с указанием
временных характеристик этапов.
4. Замерить и зафиксировать текущую производительность решения
После получения воспроизводимых тестовых сценариев\тестовых случаев, вам вам необходимо выполнить замеры производительности и зафиксировать результаты.
С "выполнить замеры", сделать трассировку работы программы - все понятно, это мы умеем.
Применительно к SAP, решение по умолчанию, это снять трассировки выполнения программ с использованием транзакций SAT, ST12, ST05.
Но почему выделено зафиксировать?
А потому что оценку эффективности сделанных оптимизаций в дальнейшем будет вестись на основании этого значения.
Оптимизация это по своей сути процесс последовательного выдвижения гипотез о методах улучшения производительности системы, их реализации и оценки результата.
Поскольку результаты не всегда ожидаемые, вы можете получить ухудшение параметров и это потребует отката неудачных изменений.
Отследить влияние конкретных изменений во всех возможных случаях использования программы невозможно. В том числе потому, что сделать воспроизводимый тест локальной программы\модуля в рамках большой системы сложно, есть много неучтенных факторов.
Вы можете столкнутся с ситуацией когда заказчик оптимизации скажет - вы "все сломали" даже после отката всех сделанных изменений.
Вот в этом случае, корректно выполненный первоначальный замер производительности по согласованному тестовому сценарию поможет вам избежать лишних споров, и ... гхм, неприятных персональных последствий.
Поэтому, всегда фиксируйте результаты перед проведением оптимизации.
5. Определить проблемные места с точки зрения производительности
Итак, мы сняли трассировку выполнения программы, иии... начинаем ее анализировать.
Для начала вспоминаем цели оптимизации - зачем мы это делаем?
Наиболее часто встречающиеся на практике цели, это:
Оптимизация по скорости выполнения (время отклика, общее время выполнения)
Оптимизация по потреблению ресурсов(потреблению памяти, нагрузке на CPU)
Подход общий для анализа по любому отдельно выделенному параметру.
В этот момент конечно, неплохо бы вспомнить, что разные архитектурные характеристики\атрибуты качества часто конфликтуют между собой, т.е.. оптимизация может быть многокритериальная.
Например:
уменьшил время отклика -> растет потребление памяти
уменьшил потребление памяти -> увеличилась нагрузка на CPU и т.д
Но, мы же не будем сразу начинать с постройки космолета, и разберем простой, всем понятный и часто встречающийся случай оптимизации по одному параметру, с фиксацией\ограничением остальных. Программа начала работать быстрее, и при этом потребление ресурсов не изменилось в худшую сторону? Все Ок, заверните, покупаем.
Наша цель на текущем этапе - понять где происходит наиболее серьезная просадка по оптимизируемому параметру. Нужно найти узкое место - его в зависимости от контекста называют критический компонент, бутылочное горлышко\bottleneck, горячая точка\hotspot.
Почему это важно? Нам нужно получить максимальный результат, минимальными усилиями.
Чем больше изменений в архитектуру\код программы вы вносите, тем больше усилий вам потребуется на разработку, последующее тестирование и исправление внесенных ошибок.
Соответственно, эффективнее всего, вносить изменения только в те части программы, которые оказывают максимальное влияние на производительность, причем не на "сферическую производительность в вакууме", а на значение конкретного оптимизируемого параметра.
Для многих разработчиков это психологически сложный момент.
Кому то хочется переписать все с нуля, кто то не может пройти мимо неоптимально написанного кода в любом месте программы.
А кто то наоборот, до ужаса боится взять на себя ответственность за изменения в критичном участке кода, и поэтому вносит правки только в безопасных и часто мало влияющих на целевой показатель компонентах.
В общем, в этот момент нужно взять себя в руки, и выбрать "правильное место для удара".
6. Определите изменения, их стоимость и выигрыш от применения
Итак, после проведения трассировки\профилирования программы, мы нашли потенциальные места для оптимизации.
Часто их несколько, но нам нужно выбрать одно место, внесение изменений в которое принесет максимальный эффект.
Какие критерии используются для выбора?
В трассировке мы видим что максимум времени\ресурса тратиться в этой точке.
Эмпирическое правило:
Тратится 20 и больше % времени. Бинго, мы идем к вам.
Меньше 10 % - пока отложим.
В тяжелых случаях в программе нет явных точек для оптимизации, и трассировка показывает равномерное распределение времени работы программы. Скажем по 1-2 % на каждый модуль.
Тут возможны два варианта:
Программа в целом написана плохо, и нужно методично идти по всей реализации и последовательно переписывать код\запросы.
Программа уже не раз оптимизировалась, из нее выжали все что могли. В этом случае, приходится рассматривать изменение архитектуры или еще раз уточнить актуальность\корректность требований к производительности с точки зрения бизнеса.
В этом месте лучше в явном виде сформулировать гипотезу которую вы будете проверять.
Зачем?
Начиная вносить изменения в код, разработчики часто скатываются на путь ковровой оптимизации, т.е. вносят исправления во все что видят в выбранном модуле\компоненте.
Иногда это правильное решение, но все же часто приводит к излишнему расходу времени и ресурсов.
Избежать этого достаточно просто. Нужно в явном виде сформулировать что вы делаете и зачем, прямо текстом, буквами описать свою гипотезу.
В качестве основы можем взять довольно популярное описание цикла генерации и проверки гипотез - HADI. Подробное описание приводить не буду, можно поискать, их есть в наличии.
Цикл HADI состоит из четырех последовательных шагов:
Hypothesis (Гипотеза): Формулируется предположение по шаблону: «Если {действие}, то {метрика} изменится на {величина } потому что { объяснение }.
Action (Действие): Проведение эксперимента для проверки гипотезы. Вносим изменения в настройки\изменяем алгоритм\добавляем индекс для таблицы БД и т.д.
Data (Данные): Сбор количественных или качественных данных, полученных в ходе действия. Выполняем повторный замер\трассировку, и смотрим как внесенное изменение повлияло на вашу метрику\параметр оптимизации.
Insights (Выводы): Анализ собранных данных и подтверждение или опровержение гипотезы. В этой точке мы должны определить, помогло ли внесенная доработка, оставляем или откатываем? Продолжаем развивать направление работ, или нужно посмотреть в другую сторону.
Сначала кажется что это бесполезный, никому не нужный формализм. Однако, во-первых, это удержит ваше внимание на том что вы делаете, а во-вторых, позволить проанализировать то что уже было сделано, каких результатов удалось добиться, и сформулировать новую гипотезу для оптимизации.
7. Выберите и реализуйте изменения
Основные подходы к оптимизации в порядке значимости:
Оптимизация БД
Оптимизация интеграции
Оптимизация неэффективных алгоритмов
1. Оптимизация БД
Ключевые задачи:
Минимизация времени выполнения запросов
Снижение блокировок и конкуренции транзакций
Улучшение масштабируемости базы данных
Сокращение загрузки сети и диска
Методы:
Профилирование запросов и анализ планов выполнения (EXPLAIN, профайлеры СУБД)
Индексация: создание и оптимизация индексов (включая составные и полнотекстовые)
Нормализация/денормализация: баланс между избыточностью данных и производительностью запросов
Оптимизация транзакций: минимизация длительности блокировок, использование уровней изоляции с учётом требований консистентности
Партиционирование данных: горизонтальное или вертикальное для масштабируемости
Кэширование на уровне данных: материализованные представления, in-memory кэширование
Оптимизация операций записи: batch-операции, уменьшение числа коммитов
Использование специальных СУБД и технологий: NoSQL, колоночное хранилище для аналитики и проч.
2. Оптимизация интеграции
Ключевые задачи:
Минимизация задержек при обмене данными между подсистемами
Уменьшение избыточного сетевого трафика и загрузки на интеграционные шины
Повышение устойчивости и отказоустойчивости интеграций
Методы:
Анализ и профилирование интеграционных транзакций (трассировка передачи данных, анализ логов)
Оптимизация протоколов и форматов обмена: выбор более лёгких форматов представления, сжатие данных
Асинхронная интеграция: внедрение очередей сообщений (Kafka, RabbitMQ)
Пакетная обработка и агрегация запросов для снижения количества вызовов\уменьшения накладных расходов
Кэширование результатов запросов к внешним системам
Оптимизация маршрутизации и балансировки нагрузки на интеграционные точки
Мониторинг и оповещения по интеграционным задержкам и ошибкам
3. Оптимизация неэффективных алгоритмов
Ключевые задачи:
Уменьшение временной и пространственной сложности вычислений
Повышение производительности критичных\"горячих" участков кода
Улучшение отзывчивости и снижения нагрузки на систему
Методы:
Анализ алгоритмов: оценка сложности (Big O), поиск узких мест на уровне кода
Рефакторинг и улучшение алгоритмов: использование более эффективных алгоритмов и структур данных (например хэш-таблиц)
Параллелизация и асинхронное выполнение
Оптимизация работы с памятью: снижение аллокаций, использование пулов объектов
Мемоизация и кэширование промежуточных результатов
Использование специализированных библиотек и аппаратных ускорителей (SIMD, GPU)
Профилирование CPU и памяти на уровне функций/методов
Выводы\заключение и прочее разное
В каждый пункт из написанных выше, можно провалиться как в Кроличью нору из всем известного произведения Льюиса Кэрролла «Алиса в Стране чудес». Провалиться и бесконечно обсуждать особенности применения какого то специфического метода оптимизации производительности, а так же сравнительных характеристик его альтернатив.
Поэтому, СТОП. Сделаем паузу, пока все это не превратилось в очередной лонгрид который никто не дочитывает до конца:)
В конце хочу привести короткий план\чеклист из обязательных шагов, который вы можете применять в своей работе.
Основные шаги проведения оптимизации производительности
Определить цель\параметры оптимизации
Получить\подготовить эталонные тестовые случаи
Провести тесты производительности и зафиксировать результаты
Определить проблемные места с точки зрения производительности
Определить изменения, их стоимость и выигрыш от их применения
Выбрать и реализовать изменения
Проанализировать результат. В случае необходимости, повторить .. Сontinue everything\непрерывное совершенствование и вот это все
И конечно хочется пожелать успехов в этом сложном, но от этого не менее интересном занятии.
"Безумству храбрых поем мы песню" :)
Список материалов
Материалов можно было бы привести много, но с учетом того, что первоначально статья была ориентирована на SAP разработчиков, не буду их разочаровывать и приведу набор базовых материалов по производительностия для платформы SAP S/4HANA.
Optimize SAP HANA Performance ( ссылки на sap note, например стоит посмотреть 2000002 - FAQ: SAP HANA SQL Optimization )
Комментарии (5)

VVitaly
23.02.2026 13:41С учетом того что при оптимизации сложных систем зачастую (~ в 90% случаев) все указанные автором параметры "оптимизируемой" системы взаимосвязаны, "легких" случаев (типа "вот тут поправить параметры/код и получить +20%") практически не бывает, хотя и есть исключения. :-)

Emelian
Интересно! Но, если бы статья сопровождалась бы еще демо-примером, то цены бы ей не было.
Приходится! Мне, вот, пришлось задуматься об оптимизации и рефакторинге собственной обучающей (иностранным языкам) программе «L'école».
Дело в том, что, я себе чуть мозги не сломал, пока не довел её до, более-менее, рабочего состояния. Но, только теперь, через полтора года публикации ее первой версии, я, наконец-то, дозрел до размышлений об ее оптимизации, рефакторинге и расширению возможностей.
В целом звучит красиво, но, малополезно, в моем случае. Производительность меня устраивает и в первой версии, а во второй я хотел бы получить:
Расширение функционала и
Понимание, как «правильно» делать проекты подобного рода, чтобы не забыть их структуру и программную логику, несколько месяцев спустя.
Вот последний момент мне и кажется наиболее важным, в данном случае.
После некоторых размышлений, пришел к выводу, что прототип программы должен разрабатывать архитектор программы. Это должен быть работающий минимальный код, в котором весь потенциальный функционал реализован в виде формальных классов – модулей. В данном случае я имею в виду оконные приложения на С++.
Все формальные классы представлены своими публичными функциями, которые ничего не возвращают (обмен данными происходит через их параметры), за исключением обработчиков событий. Те возвращают стандартные значения LRESULT (TRUE либо FALSE), но, как и все остальные публичные функции, имеют пустые тела.
Приватные части автономных классов (на уровне файлов это *.h и *.cpp модули) находятся в компетенции членов команды.
Далее, архитектор программы фиксирует вызовы формальных публичных функций в «модуле управления» (для оконных интерфейсов это, как правило, обработчики класса типа CMainFrame либо CMainWindow). Но, поскольку, эти функции – пустые, то их использование никак не проявляется.
На примере моей обучающей программы, основными, независимыми друг от друга модулями, являются: класс для работы с чтением / записью текущего состояния приложения, класс логирования, классы для работы с графикой, текстом (отображение и редактирование), звуком и данными, классы вспомогательных окон («О программе», «Помощь», «Настройка» и прочее) и т.д. и т.п.
Для всех этих классов архитектор дает их формальную реализацию. Затем раздает копии своего проекта всем членам команды и говорит, кому, какой модуль реализовывать. Такой подход позволяет достаточно просто организовать коллективную работу без использования внешних систем контроля версий, вроде, гита.
Члены команды доводят до ума свои модули и передают их архитектору. Он замещает формальные модули – их полными версиями и тестирует общую реализацию. При необходимости вносит коррективы в работу команды.
При таком подходе члены команды могут работать удаленно и иметь минимальный конфликт интересов.
Я даже не знаю, нужен ли, в таком случае, тимлид либо техлид. Наверное, да, для больших проектов. Но, для группы из нескольких программистов, думаю, без последних можно обойтись. В таком случае, архитектор «пишет» код прототипа либо ваяет его по принципу конструктора модулей.
Таким образом, используя модульное программирование либо итерационно-модульное (где предыдущие итерации, собственные для «своего» модуля каждого программиста, фактически являются просто бэкапами), можно, как мне кажется, упростить работу команды. Зато, основная нагрузка ложится на архитектора. А члены команды могут даже работать независимо друг от друга.
Однако, возможность «легко подключить модуль к проекту» (путем простой замены формальной реализации – полной) и «легко отключить модуль от проекта» (соответственно, наоборот, заменяя полную реализацию – формальной), позволяет, со временем, накаливать потенциальные модули для будущих проектов. Что дает возможность быстро создавать новые прототипы для новых проектов, аналогичного типа.
По сути, в идеале, мы получаем этакий конструктор для будущих программ.
Например, у меня есть неопубликованная программа «МедиаТекст».
http://scholium.webservis.ru/Pics/MediaText.png
Вместе, эти две программы, явно, могут иметь общие модули. При этом, в последней используются потоки и опенсорсный видеоплейер, для которых можно создать свою формальную реализацию.
Вот, приведение уже только этих двух программ к общему модульному типу (к ним можно добавить и мою третью программу – загрузчик «MiniDL» для любимых видосиков, которая опубликована здесь, на «Хабре»), позволит создать хорошую базу прототипов для будущих проектов данного типа задач. После чего можно будет уже спокойно предлагать себя в роли архитектора, на похожую работу :) .
Но, даже если программировать только для себя на уровне пет-проектов, то данный подход кажется перспективным, по крайней мере, я перестану забывать программную логику своих давно написанных программ и смогу спокойно модернизировать их до новых версий. Чем и собираюсь заняться, в ближайшее время.
Как-то так.
E_miller Автор
Есть неплохая книга "Фундаментальный подход к программной архитектуре" , Марк Ричардс, Нил Форд.
Могу порекомендовать.
К.м.к. на часть ваших вопросов она ответит
Emelian
Скачал книгу и посмотрел. Сразу наткнулся на фразу:
Вот, об этом то и речь. Я же даю и определение и способ ее достижения (применительно к оконным приложениям на С++ / WTL, под «Форточки»).
Далее пошло теоретизирование и общие слова о модульности «вообще», что, конечно, малоинтересно.
На рис. 9.1,и 23.1 там показана «визуализация архитектуры в стиле Большой ком грязи на примере реальной кодовой базы». Это типичная связь: «многие ко многим». Как минимум, её нужно преобразовать к связи: «многие к одному» и «один ко многим». У меня самого, первая версия программы организована также, что напрягло мои мозги до максимального предела. Именно в этом ключе я и работаю, с целью упрощения ее архитектурной логики.
Теоретически, меня должна была бы заинтересовать глава 14: «Архитектура, управляемая событиями», но, там она представлена на «нижнем» уровне, тогда как уже есть уровень WTL, который скрывает всю «скучную» рутину и дает механизм управления событиями на достаточно высоком уровне, из-за чего я просто обожаю эту библиотеку кода (занимаемую, в исходниках, менее полутора мегабайт!), А подход в книге предлагает мне всю эту нижнееуровневую программную логику реализовывать самому. А оно мне надо? При этом, все «конкретные» примеры оттуда, на самом деле – слишком абстрактные.
Короче говоря, книга интересная, но только для общего развития. Для конкретных задач, вроде моей: «Организовать переход от первой версии программы «L'école», ко второй, путем оптимизации сильных связей: «многие ко многим», между модулями основных классов, к более слабым связям: «многие к одному» и «один ко многим» плюс добавить новую функциональность к проекту».
Так что, за ссылку спасибо, но ускорить изобретение собственного «велосипеда», она, к сожалению., не поможет.