Введение

Мы часто говорим об алгоритмах как о "сердце" любой сложной системы. В контексте нашей платформы Гриндаты алгоритмы — это не просто код. Представьте, что данные — это деньги или документы клиентов, а алгоритмы — это инструкции и правила, которые позволяют быстро находить, сортировать, обрабатывать и сохранять эти "деньги/документы".

Процесс создания алгоритма для бизнес-логики всегда начинается с декомпозиции действий. Далее мы переводим эти действия на алгоритмический язык, подбирая оптимальные пути решения. Но чтобы делать это быстро и эффективно, необходима прочная концептуальная база.

Формулы удачного написания алгоритма не существует, поскольку задачи всегда разного толка и сложности. Однако понимание основных парадигм программирования — это первый и главный ключ к написанию оптимально работающих алгоритмов. Наши алгоритмы являются мультипарадигменными, поэтому рассмотрим два основных подхода, лежащих в их основе: ООП и ФП.

Концептуальная основа: ООП (Объектно-ориентированное программирование)

Концепция ООП лежит в основе структуры и окружения нашей платформы. Понимание ООП необходимо аналитику для:

  • Качества обработки требований: Умение выделять сущности, их свойства и связи.

  • Понимания платформы: Лучшее понимание архитектурных решений, предлагаемых разработчиками.

  • Проектирования гибких систем: Создание решений, которые легко изменять и переносить.

Рассмотрим ключевые понятия ООП на знакомой банковской аналогии:

  • Класс vs Объект:

    • Класс — это чертеж, инструкция или шаблон для создания объектов. Аналогия: чистый бланк Кредитной заявки. В шаблоне прописаны пустые поля (ФИО, сумма) и действия/методы ("отправить на проверку", "одобрить").

    • Объект — это уже конкретная сущность, созданная по шаблону-классу, с реальными данными. Аналогия: заполненный бланк "кредитнаяЗаявка_Иванова" на 500 000 руб..

  • Интерфейс: Более абстрактное понятие, которое описывает, что объект должен делать, но не описывает, как он это будет делать. Аналогия: Банковское отделение. Интерфейс предоставляет набор услуг ("открыть счет", "выдать наличные"). Реализация может быть разной: центральный офис, дополнительный офис или банкомат. Интерфейс позволяет разным объектам выполнять один и тот же набор действий.

Принципы ООП

  • Абстракция: Создание простой "модели" сложного предмета, содержащей только самые важные детали для решаемой задачи. Аналогия: форма Заявления на кредит. Вам не нужно знать все процессы скоринга; вы видите только поля (ФИО, доход) — это абстракция всего кредитного процесса.

  • Инкапсуляция: Объединение данных и методов работы с ними в одной "капсуле" (объекте) с контролируемым доступом. Внутренняя "кухня" скрыта. Аналогия: Банкомат. Вы взаимодействуете через строгий интерфейс (вставили карту, ввели PIN) и не знаете, как он внутри пересчитывает купюры и связывается с сервером. Ваши данные защищены.

  • Наследование: Создание нового объекта на основе существующего, перенимая его свойства и поведение. Аналогия: банковские продукты. Базовый продукт "Счёт" (номер, баланс). На его основе создается "Депозит", который наследует свойства Счета, но добавляет свои (процентная ставка, срок окончания).

  • Полиморфизм: Возможность использовать одно и то же действие для работы с разными типами объектов. Аналогия: "Рассчитать проценты". Для "Депозита" расчет происходит по одним правилам (конец срока), а для "Кредитной карты" — по другим (ежемесячно, на остаток долга). Для пользователя это одно действие, но внутри система выполняет разные алгоритмы.

Концептуальная основа: ФП (Функциональное программирование)

Хотя наше окружение основано на ООП, сами алгоритмы часто используют подходы Функционального программирования (ФП), которое обеспечивает предсказуемость и надежность кода. В ФП программа — это набор функций, преобразующих входные данные в выходные. Ключевая идея: функции должны быть похожи на математические, обеспечивая идемпотентность.

Понимание ФП выгодно аналитику, так как:

  • Помогает формализовать бизнес-правила в виде чистых, атомарных требований, которые легко тестировать.

  • Способствует описанию бизнес-процессов как цепочки преобразований данных (Data Flow), что делает спецификации четкими.

Ключевые принципы ФП

  • Неизменяемость данных (Иммутабельность): Исходные данные не изменяются. Для внесения изменений создается новая версия. Аналогия: ошибочная транзакция. Вместо удаления или изменения ошибочной операции, создается новая транзакция на ту же сумму со ссылкой на исходную. Это сохраняет всю историю произошедших событий.

  • Чистые функции (Идемпотентные): При одних и тех же входных данных, всегда возвращают один и тот же результат и никак не влияют на работу системы (не меняют глобальные переменные, не пишут в лог). Они ТОЛЬКО ВЫЧИСЛЯЮТ. Пример: Функция рассчитатьПроцент(сумма, ставка, срок) всегда вернет одинаковое значение, независимо от того, кто и когда ее запустит..

  • Функции первого класса: Функции, которые могут выступать в качестве аргумента для других функций. Пример: Функция обработатьСписокКлиентов принимает в качестве аргумента список клиентов и другую функцию, например, ОтправитьEmail или ОтправитьSMS, и применяет ее ко всему списку. Это повышает эффективность.

  • Отсутствие побочных эффектов: Функция не должна менять что-либо за своими пределами, кроме своего явного предназначения. Пример: Функция проверитьВозможностьКредита должна только проанализировать доход и кредитную историю, и вернуть ответ: "одобрено" или "отклонено". Она НЕ ДОЛЖНА самостоятельно менять статус заявки в БД или отправлять уведомление.

Алгоритмы платформы: "Хорошие" и "Плохие" практики

Алгоритмы в нашей платформе исходно на уровне back-end написаны на языке Groovy. При этом они являются мультипарадигменными: ООП учит нас структурировать окружение (объекты, таблицы), а ФП приучает правильно использовать функции внутри алгоритма.

Качество работы алгоритма, его скорость и понятность напрямую зависят от окружающих настроек и того, как написан сам алгоритм. Плохо спроектированная объектная модель (дублирующие справочники, нелогичные связи) приведет к тому, что даже хороший алгоритм будет работать плохо, требуя "костылей".

Ниже приведен список практик, которые помогут вам писать "хорошие" алгоритмы.

Список, дающий "минус-вайб" вашему алгоритму

Избегайте этих распространенных ошибок, которые ведут к медленной работе и сложному сопровождению:

  • Чрезмерное использование SQL. Стремитесь минимизировать SQL внутри алгоритма.

  • Использование функции Objects по таблице, где сотни тысяч или миллионы экземпляров.

  • Поиск не по индексированным полям в функции filterAlg.

  • Втюхивать в один алгоритм всю логику.

  • Составлять алгоритм из бесконечной вложенности других алгоритмов (алгоритм → вложенный алгоритм → ещё один вложенный).

  • Не пользоваться специализированными функциями, например, для расчета вычислимых показателей или при работе с лимитами.

  • Не тестировать свои алгоритмы самостоятельно. 5 секунд на тест сэкономят часы срочных работ на продакшене.

  • Доверять написание кода ИИ. ИИ не знает внутренних ограничений нашей платформы и использует избыточные конструкции, которые не подходят для Groovy в Гриндате.

Как писать "правильные" алгоритмы

  • Комментарии и осмысленное наименование: Комментарии и логичные имена переменных позволяют вам и вашим коллегам быстро вникнуть в суть происходящего, особенно в сложных конструкциях.

  • Используйте Структуры данных: Структуры данных (массив, хэш, очередь, стек) позволяют зафиксировать набор элементов в оперативной памяти и значительно сократить время работы алгоритма. Например, они незаменимы при работе с ETL.

  • Логически дробите алгоритм: Дробление важно и необходимо, но должно быть логически обосновано. Вместо одного огромного алгоритма создавайте несколько маленьких, например, используя вложенный алгоритм в разных местах.

  • Экранирование данных: При работе с интеграциями, JSON, XML или формировании, например, гиперссылки в SendPopUpMessage, важно экранировать данные (например, с помощью функции text для HTML), чтобы избежать ошибок и чтобы front-end "не съел" теги.

  • Учитывайте строгую типизацию данных.

Комментарии (1)


  1. valerychesnokov
    09.10.2025 05:08

    • Чрезмерное использование SQL. Стремитесь минимизировать SQL внутри алгоритма.

    Доброго дня. Скажите, пожалуйста, чем применение SQL такую немилость вызвало? Ведь грамотно написанный СКЛ источник отработает быстрее, чем в цикле крутить объекты с фильтрами. Особенно если в СКЛ несколько таблиц соединено сложной логикой.
    Можно как-то раскрыть эту мысль на примере?
    П.С: с платформой GD знаком 3.5 года.