Об уровне абстракции и сложности системы

21.12.17

Разработка - Математика и алгоритмы

В среде 1С почти не приходится слышать таких терминов, как уровень абстракции, декомпозиция и управление сложностью. Тем не менее, эти термины следует понимать, а подходы применять на практике, поскольку правильно выбранный уровень абстракции ведет к упрощению и увеличению устойчивости программного кода на порядки.

Мы привыкли к тому, что в 1С есть два уровня абстракции: уровень платформы и уровень бизнес-логики.

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

Следующий уровень - это уже как раз та самая фура с хлебом и логика действий с ней (оприходование хлеба по количеству и качеству, невозможность оприходования без согласованного договора, отсрочка платежа и т.п.), т.е. уровень бизнес-логики.

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

Зачем же нужны посредники, не проще ли запрограммировать все напрямую?

Бывает проще, бывает - нет.

Если перед нами стоит задача раскрасить неоплаченные заказы в красный цвет - довольно сложно придумать какой-либо обобщающий подход, который будет более универсален, при соответствующей настройке покрывать текущую потребность и проще в реализации.

Но можно привести другой пример: требуется вести остатки номенклатуры в разрезе документов: Заказ поставщику, Заказ на перемещение, Заказ клиента, Заказ на внутреннее потребление, Заявка на возврат товаров от клиента... Классический остаточный регистр накопления. Типа Товаров к поступлению, Заказов клиентов и т.п. (т.е. заказ поставщику начисляет - поступление списывает, заказ на перемещение начисляет - перемещение списывает и так 5 пар документов)

В типовой УТ эта задача решена "в лоб", с получением данных для проведения отдельно в каждом документе, при чем почти для каждой пары еще и регистр отдельный. Вопрос о том, почему в типовой так сделали, рассматривать не будем (спойлер: не потому что они плохие, а потому что у них специфика такая), рассмотрим, какие есть альтернативы.

Поднимем ставки Повысим уровень абстракции.

Стоит задуматься: зачем писать 10 обработок проведения? Нельзя ли написать одну или две? Зачем нам вообще знать, будет это документ заказ на перемещение или заказ на что-нибудь еще? Нельзя ли сформулировать требования каким-то более общим образом? При обдумывании этих вопросов вы столкнетесь со сложностью обобщения: таб.часть с номенклатурой может называться не только Товары. Колонка с количеством может называться не только Количество. Ссылка на документ-заказ тоже может называться по-разному.

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

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

Не стоит ли пойти дальше?

Глядя на вторую формулировку задачи, можно попытаться пойти дальше: зачем употреблять термины "номенклатура" и "документ-заказ"? почему бы не переформулировать задачу так: требуется разработать механизм проведения документа; тип регистратора, пути к 2 измерениям и 1 ресурсу указывать через настройки.

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

А потом еще: разработать механизм, записывающий произвольный объект или набор записей в базу по произвольному событию объекта-источника.

И так, в общем, можно продолжать пока не будет задан главный вопрос жизни, вселенной и всего такого... (давным давно, когда трава была зеленее, кто-то пошел по этому пути и зашел так далеко, что в результате появился БИТ.Финанс. Кто знает - тот понимает)

Понятно, что нужно где-то остановиться.

Очевидно, что с повышением уровня абстракции сложность нашей доработки будет сначала снижаться (иначе не стоило и связываться), а затем повышаться (последняя формулировка уже тянет на разработку чуть ли не Конвертации данных).

На своих проектах, как правило, я выбираю одну из трех возможных тактик выбора уровня абстракции:

  1. Точка минимальных издержек - т.е. выбирается наименее трудозатратный вариант. Этот вариант выбирается, когда разрабатываемая функциональность вряд ли будет иметь какое-то развитие и скорее всего останется статичной. Это, как правило, "обычные задачи".
  2. Точка начальных издержек - т.е. выбирается наиболее абстрактный вариант, трудозатраты по которому не превышают тех, которые имели бы место при решении задачи "в лоб". Такой вариант выбирается, если функциональность обещает развиваться, но еще не выглядит весьма универсальной. Это, например, задача приведенная выше.
  3. Точка максимальных затрат - т.е. выбирается наиболее абстрактный вариант, который мы себе только можем позволить реализовать. Пишем и переписываем код до тех пор, пока нас не выгонят с работы код не станет идеален. Такой вариант выбирается, когда функциональность выглядит достаточно универсальной для того, чтобы разрабатывать ее независимо от текущего проекта, как отдельную библиотеку. Это, как правило, какие-то транспортные модули, подсистемы сверок данных и т.п.

Важный прием - декомпозиция.

Иногда стоящая перед программистом задача выглядит довольно сложной и повышение уровня абстракции "просится" само собой, но при попытке сформулировать задачу в более общем виде что-то постоянно мешает, формулировка выглядит "корявой" и ни разу не упрощает реализацию.

У меня такое было с бухгалтерией: требовалось загружать из документы из УТ в БП по... не совсем линейному принципу, ну вы понимаете, и при попытке сделать систему которая подстраивалась бы под меняющиеся требования, мне мешало одно обстоятельство: сгенерировать кучу типов документов по настройкам внутри интерфейса обмена никак не получалось.

Тогда пришло осознание, что я должен отделить мух от котлет задачу генерации документов от задачи их транспортировки. С этого момента все пошло как по маслу: была написала легкая, гибкая и элегантная подсистема генерации документов и подсистема "рассовывания" документов по нужным бухгалтериям.

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

Обратная сторона медали.

Как и в любом бесплатном сыре, в повышении уровня абстракции есть минус. Вы должны быть готовы к тому что все последующие доработки следует приводить к тому же уровню абстракции, на котором выполнена разработка. Например, если в задачу про движения по регистру накопления, реализованную в постановке №2 внести требование "заказы клиентов проводить только в статусе Согласован" - это требование следует привести к тому же уровню абстракции, что и вся разработка: т.е. абстрагироваться от конкретного документа и, как следствие, от конкретного поля и значения его статуса, и пилить что-то вроде проверки соответствия документа неким условиям, конкретные реквизиты, типы сравнения и значения которых задаются в пользовательском интерфейсе.

Из этого принципа есть следствия:

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

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

Есть правда и тут свои лайфхаки: если новое требование уж совсем не укладывается в выбранную архитектуру - можно запилить отдельную доработку со своим собственным уровнем абстракции. Например, для задачи со статусами, можно прикинуться, что эта задача не связана с предыдущей и сделать отдельную, независимую функциональность которая будет очищать движения, если документ не находится в нужном нам статусе.

И при чем же здесь сложность?

Дело все в том, что доработки, разработанные на более высоки уровнях абстракции, как правило, оказываются более простыми. Там, условно говоря, нечему глючить: если в нашем примере провелся документ одного типа - проведение документа второго типа - это вопрос правильной настройки; в программной части все уже проверено.

Ради получения этого эффекта доработку можно разбить не на два уровня абстракции (как в нашем примере: абстрактная процедура проведения и бизнес-логика в настройках), а на большее количество уровней. Но здесь, опять же, следует чувствовать баланс: каждый следующий уровень, с одной стороны, должен быть обоснован снижением сложности, с другой - будет негативно сказываться на гибкости системы к изменениям.

Архитектура уровни абстракции

См. также

Математика и алгоритмы Программист Платформа 1C v8.2 Конфигурации 1cv8 Россия Абонемент ($m)

На написание данной работы меня вдохновила работа @glassman «Переход на ClickHouse для анализа метрик». Автор анализирует большой объем данных, много миллионов строк, и убедительно доказывает, что ClickHouse справляется лучше PostgreSQL. Я же покажу как можно сократить объем данных в 49.9 раз при этом: 1. Сохранить значения локальных экстремумов 2. Отклонения от реальных значений имеют наперед заданную допустимую погрешность.

1 стартмани

30.01.2024    3242    stopa85    12    

38

Математика и алгоритмы Бесплатно (free)

Разработка алгоритма, построенного на модели симплекс-метода, для нахождения оптимального раскроя.

19.10.2023    7661    user1959478    52    

36

Математика и алгоритмы Разное Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

Расширение (+ обработка) представляют собою математический тренажер. Ваш ребенок сможет проверить свои знание на математические вычисление до 100.

2 стартмани

29.09.2023    3178    maksa2005    8    

26

Математика и алгоритмы Инструментарий разработчика Программист Платформа 1С v8.3 Мобильная платформа Россия Абонемент ($m)

Что ж... лучше поздно, чем никогда. Подсистема 1С для работы с регулярными выражениями: разбор выражения, проверка на соответствие шаблону, поиск вхождений в тексте.

1 стартмани

09.06.2023    10946    7    SpaceOfMyHead    18    

61

Математика и алгоритмы Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Три задачи - три идеи - три решения. Мало кода, много смысла. Мини-статья.

03.04.2023    4433    RustIG    9    

25

Механизмы платформы 1С Математика и алгоритмы Программист Платформа 1С v8.3 Россия Бесплатно (free)

В статье анализируются средства платформы для решения системы линейных уравнений в 1С. Приводятся доводы в пользу некорректной работы встроенных алгоритмов, а значит потенциально некорректного расчета себестоимости в типовых конфигурациях.

23.11.2022    3599    gzharkoj    14    

25

Математика и алгоритмы Программист Платформа 1С v8.3 Россия Абонемент ($m)

Обычно под распределением понимают определение сумм пропорционально коэффициентам. Предлагаю включить сюда также распределение по порядку (FIFO, LIFO) и повысить уровень размерности до 2-х. 1-ое означает, что распределение может быть не только пропорциональным, но и по порядку, а 2-ое - это вариант реализации матричного распределения: по строкам и столбцам. Возможно вас заинтересует также необычное решение этой задачи через создание DSL на базе реализации текучего интерфейса

1 стартмани

21.03.2022    9053    7    kalyaka    11    

44
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. brr 184 21.12.17 11:58 Сейчас в теме
Единственная возможность повышать уровень абстракции это оператор Выполнить. И на том спасибо.
2. genayo 21.12.17 12:07 Сейчас в теме
Да, такие подходы приводят к созданию конфигураций, где совсем не используются регистры накопления и документы с табличными частями. Работать с ними будет удобно, если сможешь разобраться. Но на то, чтобы с нуля понять, как оно работает, уйдет очень много времени, и такие знания применить будет негде, кроме как на этом конкретном проекте.
3. neikist 21.12.17 12:53 Сейчас в теме
Проблема смешения уровней абстракции которую вы тут затронули в т.ч. довольно часто встречается к сожалению. Даже если не брать описанные вами абстракции, "макроуровневые" так сказать, на "микроуровне" очень часто можно встретить в одной процедуре сразу и проверку условий каких то уровней так на 4-5 вложенных если, и пару циклов, и установку флагов каких нибудь, и еще вывод печатки. Все в одной куче.
4. Сурикат 401 21.12.17 13:37 Сейчас в теме
Спасибо за статью. Последнее время о программировании на infostart пишут мало. Может быть стоило начать сразу с применения SOLID с оглядкой на 1С? =)

По-моему вы привели очень неудачный пример. Чем формирование настроек принципиально отличается от формирования таблиц для движений? Только какими буквами это написано. Причем в типовой конфигурации подход используются более гибкий, т.к. позволяет применять более сложную логику при формировании движений. А уже класс ФормировательДвижений (ОбщийМодуль Проведение) пишет данные в регистр, но сделано это больше для уменьшения дублирования кода, чем для борьбы со сложностью.

Т.е. вывод статьи немножко расходиться с примером.

И вам не кажется, что если доработку должен вести квалифицированный программист (в идеале автор!!!!), то где-то что-то пошло не так (мы неправильно назвали классы, ошиблись при проектировании, наша абстракция оказалась плоха)?

У меня был случай, когда делал свой "класс" дата, для переопределения операции сложения. Тогда такой подход мне здорово помог распутать свою писанину. А в остальном объектов платформы за глаза хватает.

А можете привести примеры, где вам не хватило объектов, которые предлагает платформа, и пришлось какими-то ухищрениями повышать уровни абстракции именно для уменьшения сложности?
5. pm74 203 21.12.17 18:00 Сейчас в теме
(4)
мы неправильно назвали классы, ошиблись при проектировании, наша абстракция оказалась плоха
для этого абстракция должна быть представлена в виде некоторой модели которая , в идеале, может быть верифицирована
6. Сурикат 401 21.12.17 18:08 Сейчас в теме
(5)
Ну т.е. в идеале должен быть code-review =)
7. pm74 203 21.12.17 18:12 Сейчас в теме
(6) в самом идеальном идеале )) формальная верификация еще на этапе моделирования
8. genayo 21.12.17 19:30 Сейчас в теме
(4) Так наоборот, при повышении уровня абстракции становится очевидно, что от большого числа объектов вполне можно отказаться...
9. Manoshkin 357 22.12.17 08:39 Сейчас в теме
.... и не документ должен писать в регистры, а регистр знать как наполнять себя по событиям внешнего мира.... (что-то навеяло :)
10. m-rv 973 22.12.17 08:56 Сейчас в теме
(9)
Это интересная мысль, спасибо
11. Сурикат 401 22.12.17 10:33 Сейчас в теме
Такой подход опасен

Ведь при изменении любого события придется изменять сам регистр и получиться объект с огромным количеством обязанностей, который будет сложно сопровождать
12. l1ike 26.12.17 08:49 Сейчас в теме
(9)
Только не Регистр должен сам себя наполнять, а Сервис. Сервис учета НДС, к примеру. А по скольким уж там регистрам Сервис распихает информацию, должен решать сам сервис. Документы же должны уметь генерировать события понятные сервису.

Долгие годы мучает вопрос, почему в 1с не срослись СтруктураШапкиДокумента, XDTO и сервисно ориентированный подход.
Сурикат; Manoshkin; +2 Ответить
13. Сурикат 401 29.12.17 23:22 Сейчас в теме
(12)
Слишком сложно для большинства? =(
14. NoRazum 29 21.03.18 13:02 Сейчас в теме
(12) Когда такое случиться будет счастье, но это уже будет не 1С, а что-то другое
15. 2ncom 114 03.06.18 06:47 Сейчас в теме
Очень интересно про абстракцию данных.
Но вот документы и справочники, мне кажется, логичнее отнести к абстрактному уровню, поскольку они непосредственно отражают предметы учета — участвуют в построении бизнес логики.
Оставьте свое сообщение