#Область ВНЕШНИЕ_ВЫЗОВЫ или MVC в 1С, библиотечность и упрощение интеграции кода

Программирование - Практика программирования

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

Вместо предисловия - парочка флешбэков.

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

ОбщегоНазначенияКлиентСервер.СообщитьПользователю

и

ОбщегоНазначения.ЗначениеРеквизитаОбъекта

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

2. Когда понадобилось портировать нашу разработку "Все службы доставки в Вашей 1С без изменения конфигурации" с УТ 11.2 на УТ 11.1, оказалось, что есть функции, которые в обеих конфигурациях одинаковые, но по сути разные. Например:

УправлениеКонтактнойИнформациейКлиент.ОткрытьФормуКонтактнойИнформации

в 11.1 принимает 5 параметров, а в 11.2 - три, при этом почти все они необязательные, т.е. на несоответствие количества параметров, если их три в вызове, ошибки не будет, но работать тоже не будет.

3. А ещё бывает так, что функция в УТ 11.1 называется ПОЧТИ также, как в УТ 11.2. Получаешь ошибку, переносишь функцию из одной конфигурации, а там уже есть такая же, только называется на четыре буквы короче.

4. Но самый 1С-стайл - это функции, которые называются одинаково, а действуют по-разному! Например:

УправлениеКонтактнойИнформацией.ПроверитьАдрес

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

MVC - WTF?

Что такое MVC лучше расскажет Википедия. В самом общем смысле это идея о том, что Интерфейс не должен знать, что делается в Базе, а Базе должно быть совершенно наплевать, что там в Интерфейсе и вообще интерфейсов может быть много разных или не быть вообще. А общаться База и Интерфейс должны через маленькую дырочку - Контроллер. Зачем это нужно? Чтобы сделать и базу, и интерфейс максимально независимыми, чтобы для изменения базы не нужно было менять все интерфейсы, а при изменении интерфейсов не нужно было трогать базу.

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

Некоторые робкие потуги разделить Логику и Представление уже есть в типовых конфигурациях. Но образцов для подражания там ещё очень немного. Библиотеки, которые прочно вошли в жизнь других языков программирования, начали появляться и в 1С. В основном это - БСП. И там как раз очень не хватает... "библиотечности", возможности безболезненно взять какую-то область (механизм), безболезненно вынуть и вставить в другую среду, без вычищения "торчащих проводов".

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

Обратно в 1С

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

#Область ОбщийКод

Процедура ЧёНибудьСделать(КакиеТоПараметры)
    
    Реквизит = Внешний_ЗначениеРеквизитаОбъекта(НашаСсылка, "НашРеквизит");
    Внешний_СообщитьПользователю("Вот такой реквизит: " + Реквизит);
    
КонецФункции

#КонецОбласти


#Область ВнешниеВызовы

Процедура Внешний_СообщитьПользователю(Текст)
    
    ОбщегоНазначенияКлиентСервер.СообщитьПользователю(Текст);
    
КонецПроцедуры

Функция Внешний_ЗначениеРеквизитаОбъекта(Ссылка, Реквизит)
    
    Возврат ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, Реквизит);
    
КонецФункции

#КонецОбласти

Что получилось?

  • В любой момент времени известно, сколько и какие есть из этого модуля внешние вызовы. При переносе такого модуля ещё до первого теста можно провести 90% работ по интеграции, проверить все вызовы на их соответствия ожиданиям, переопределить то, что изменилось, проверить те самые функции, которые одинаково называются, но действуют по-разному и прочие подводные камни.
  • При любых ошибках во время интеграции можно прежде всего смотреть на небольшую область кода с внешними вызовами. Ведь внутреннее взаимодействие в коде не поменялось, ошибки, скорее всего, именно на стыках с внешней средой. А все стыки у нас теперь связаны в один пучок, не нужно ходить по всему коду и искать "торчащие провода".
  • Зачастую внешние вызовы - это функции общего назначения, вроде сообщений пользователю и прочих. При этом они же зачастую могут меняться. Да и вызываются они обычно из большого количества мест. И здесь тоже всё стало проще - нужно, например, не сообщать пользователю, а писать в журнал регистрации? Или не вместо, а вместе? Пожалуйста - меняем одну функцию и вуаля.
  • Простой, красивый, легко читаемый, легко дорабатываемый код. Мухи у нас отдельно от котлет, появляется некое подобие Модели, которая работает сама по себе, и Контроллера, который отвечает за внешнее взаимодействие.

Спасибо за уделённое время, надеюсь, кому-то данная информация поможет в разработке.

См. также

Комментарии
1. kiruha Дронов (kiruha) 360 12.10.17 14:24 Сейчас в теме
А если будет
ОбщегоНазначения.ЗначениеРеквизитаОбъекта
и
ОбщегоНазначенияКлиентСервер.ЗначениеРеквизитаОбъекта

в одном модуле ?

или даже в разных, но таким образом имеющие разное исполнение
Программист увидит Внешний_ЗначениеРеквизитаОбъекта и не заметит что это разное исполнение в 2 случаях,
либо придется дергаться по коду вверх вниз что более неудобно, чем было ранее в 1С

И вообще общие модули это не просто бессмысленное нагромождение процедур и функций,
это по задумке аналоги классов со своими методами, которые должны облегчать чтение кода
2. Гуков Ярослав (for_sale) 192 12.10.17 15:04 Сейчас в теме
(1) Тут сразу несколько вопросов - а для чего в разных модулях делать функции с одинаковым названием и разным исполнением? Различия функций в разных версиях ещё понятно, но одинаковые функции с разным функционалом в разных модулях - это, по-моему, даже для 1С слишком:) И даже если они есть - для чего их вызывать из своего модуля вместо одной из них?

Но в принципе, по-моему, ответ на ваш вопрос очевиден - назвать их по-разному. Вам сама 1С не даст назвать две функции в модуле Внешний_ЗначениеРеквизитаОбъекта. Вторую просто назовёте по-другому, Внешний_ЗначениеРеквизитаОбъекта_КотораяБылаСозданаЗачемТоЕщ­ёИПочемуТоЕщёИИспользуется, например.

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

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

Так я ж и не говорил, что бессмысленное. Вы, мне кажется, невнимательно прочли пост. Смысл в том, чтобы все эти вызовы поместить в одно место и легко (легче, чем было) их контролировать. Ни в коем случае я не пытался оспаривать нужность самого существования таких вызовов. Просто призвал не размазывать их по всему коду.
13. kiruha Дронов (kiruha) 360 12.10.17 18:25 Сейчас в теме
(2)
1)В типовых встречается одинаковые.

2) Предположим у меня есть общий модуль ОбменЦБанк

И в коде используются

ОбменЦБанк.ОтправитьСообщение()
ОбменЦБанк.ОтправитьПакет()
ОбменЦБанк.ПринятьПакет()
ОбменЦБанк.ПолучитьПрофильДоступа()
ОбменЦБанк.Верификация()

.....

Зачем мне все это заменять на
ВнешняяФункция_ОтправитьСообщение() 
и т.п.
И зачем мне собирать в одном месте, если никаких изменений вызовов не планирую,
а если изменю раз в год, то и код поправлю ?

Или это только для типовых ?
20. Гуков Ярослав (for_sale) 192 13.10.17 08:42 Сейчас в теме
(13) Есть такое понятие - хороший код. Это когда всё однотипно, всё понятно, нет завязки на программиста, легко поддерживается и легко читается. Я не претендую вот эту практику из поста ввести в хороший код, но могу точно сказать, когда начинаются вот такие вопросы - а зачем мне, я же раз в год или вообще никогда - в результате получается yet another 1C project, то, что мы видим постоянно, Г-код.

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

У вас ключевое слово - Я. Вы считаете, что никто никогда не будет после вас поддерживать этот код, а вы и так знаете, что там где. И так все думают.

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

Я и не говорю, что вот это выделение внешних вызовов жизненно необходимо. Когда-то его было бы неплохо использовать и я попытался собрать несколько случаев этого в посте. Когда-то, возможно, не стоит.
roofless; neikist; lukashov_as; brr; +4 Ответить
3. Сан Саныч (herfis) 134 12.10.17 15:20 Сейчас в теме
Если проводить аналогии, то это скорее интерфейсы, адаптеры и иже с ними.
Но так - идея норм. В собственных подсистемах/обработках, внедряемых в типовые, тем более тиражируемых, имеет смысл.
for_sale; +1 Ответить
4. Сан Саныч (herfis) 134 12.10.17 15:23 Сейчас в теме
Сам задолбался портировать простейшую обработку с минимумом внешних зависимостей между разными версиями БСП. То переименуют что-нить молча, то в другой модуль молча перенесут, то вообще непонятно теперь где искать... Красавцы. Вечная альфа какая-то.
IvanovAV; awk; TreeDogNight; the1; CyberCerber; for_sale; +6 Ответить
6. Сан Саныч (herfis) 134 12.10.17 15:35 Сейчас в теме
(5) Чел просто предлагает все внешние зависимости "своего" куска функционала, собирать в одном месте и вызывать через функции-адаптеры.
Если это просто одна обработка - будет просто вынос в отдельные секции программных модулей этой обработки. Если целая подсистема - то да, полный набор модулей по их видам. Список процедур составляется "от обратного". Что используется, то и выносится.
В итоге при минорных правках внешнего API можно будет обойтись правкой в одном месте, а не во всех точках вызова.
Ну, это как я понял исходный посыл.
CSiER; roofless; for_sale; +3 Ответить
15. GHOST whitegh0st (whitegh0st) 12.10.17 21:15 Сейчас в теме
(7)тут скорее всего mvvm потому как внесение части функций в отдельный модуль тяжело назвать контроллером. Да и вообще странно использовать эти термины в отношении 1С, потому как мы не можем, например, взять и использовать другой компонент для представления не меня при этом модели
16. Гуков Ярослав (for_sale) 192 12.10.17 23:11 Сейчас в теме
(15)
внесение части функций в отдельный модуль

Тут кто-то из нас кого-то не понял, или я, или вы :) Я не говорил о выносе части функций в отдельный модуль, только о том, что функции, которые тянутся в другой модуль, вынести в отдельную часть модуля и обнести колючей проволокой выделить визуально.

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

странно использовать эти термины в отношении 1С

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

мы не можем, например, взять и использовать другой компонент для представления не меняя при этом модели

Почему не можем? Классический пример из википедии - представление данных в виде графика, диаграммы или таблицы. Мы точно также можем сделать (и зачастую делаем) несколько отчётов с одними и теми же данными, но в разной форме и разном сочетании. MVC аз из - есть база, есть интерфейс и есть контроллер в виде СКД, который их связывает. Другое дело, что в 1С вообще тяжело найти другие достойные примеры. Как было всё в кучу, так и есть, поэтому зачастую так и получается, как вы написали - нельзя поменять представление, не меняя модель. Но нельзя не потому, что невозможно, а потому что так написано, что проще застрелиться, чем поменять.
yurii_host; JorjKrut; +2 1 Ответить
30. Артём Андриянов (CSiER) 13.10.17 18:58 Сейчас в теме
(16), упоминание MVC в статье лишнее. Там другая цель - разделить сущности. На примере того же механизма СКД - он "сам себе MVC" :) model -схема компоновки (сам запрос, параметры и т.п.), view - настройки пользователя конкретного варианты отчета и т.д., а controller - "черный ящик с кнопкой сформировать", с помощью которого получается макет компоновки и затем уже результат компоновки отображается пользователю. СКД позволяет менять интерфейс без изменения модели (одни и те же данные можно представить в виде таблицы и, например, диаграммы).
Описанное решение - скорее паттерн прокси из банды четырех (очень отдаленно). Все описанное IMHO.
55. GHOST whitegh0st (whitegh0st) 17.10.17 16:28 Сейчас в теме
(30) вот да я именно это и пытался донести что mvc это механизм для разделения сущностей, т.е. модель ничего не знает как визуально она будет представлена, вьюха соответственно ничего не знает о том как выглядит модель, контроллер тоже не в курсе что внутри вьюхи происходит и как например собирается и где хранится модель.
11. p m (pm74) 34 12.10.17 16:05 Сейчас в теме
(0) а медный кабель зачем ?
18. Денис Харченко (nomadon) 133 13.10.17 06:46 Сейчас в теме
(11) во-первых просто красиво, во-вторых демонстрация положения дел «после», ну и в тексе что то написано про провода)))
brr; for_sale; +2 Ответить
21. p m (pm74) 34 13.10.17 09:11 Сейчас в теме
(18) что то вроде "маленькой собачки Фаворского"?
35. Гуков Ярослав (for_sale) 192 13.10.17 21:38 Сейчас в теме
(21)
маленькой собачки Фаворского

Когда работаю в коде 1С, перед глазами часто всплывает картина - комната, полностью увешанная оголёнными проводами, которые тянутся отовсюду везде. И когда нужно что-то своё вставить в сеть, приходится лазить по проводам с риском быть убитым и искать нужные, с нужным напряжением и силой тока, а потом прикручивать свои провода к этим :) А хотелось бы просто взять вилку и вставить в розетку. И чтобы все провода были изолированы, связаны в пучок и всё было легко найти.
37. p m (pm74) 34 13.10.17 21:47 Сейчас в теме
(35) ну извините просто не понял вашей ассоциации
12. Константин Гейнрих (CyberCerber) 159 12.10.17 16:18 Сейчас в теме
Хорошая практика.
Когда писал универсальную обработку, которая должна работать на разных версиях БСП, приходилось создавать такие "тупые" методы:

&НаКлиенте
Функция ОбластьМакета(Макет, Секция)
	
	Попытка
		Возврат УправлениеПечатьюКлиент.ОбластьМакета(Макет, Секция);
	Исключение
		Возврат УправлениеПечатьюКлиент.ПолучитьОбласть(Макет, Секция);
	КонецПопытки;
	
КонецФункции
Показать


И таких функций у меня в обработке в 1000 строк штуки 4 - 5.
А вынести все вызовы внешних модулей, даже если пока в них нет различий, идея хорошая.

А разработчикам БСП можно сказать только одно: Пожалуйста, не делайте такое с методами, которые могут использовать сотни программистов. Это же просто кощунство!
IvanovAV; the1; sansys; for_sale; +4 Ответить
19. Денис Харченко (nomadon) 133 13.10.17 06:47 Сейчас в теме
(12) в бсп есть функции получения версии бсп, можно без попытки обойтись
14. борян петров (TODD22) 16 12.10.17 18:29 Сейчас в теме
Пару раз наступив на изменение процедур в БСП, стал просто все необходимые процедуры копировать из БСП в свои модули. Если конечно за ними ещё много всего не потянется.
IvanovAV; kiruha; +2 Ответить
17. Артано Майаров (Артано) 322 13.10.17 02:13 Сейчас в теме
В разработке применяю такой же прием, но местные методы не обзываю по особому. Вообще это не что-то сверхъестественное, а правило хорошего тона при разработке промышленных приложений. И это не только для переноса кода, но и вообще для масштабируемости и облегчения переопределения.
for_sale; +1 Ответить
22. Максим Макаров (mxs89) 3 13.10.17 09:19 Сейчас в теме
в приведенном примере автор просто обернул интерфейсные функции общего модуля (модели). если что то поменяется в интерфейсе модели, добавят новый параметр, тогда придется его так же добавить как в обертке, так и в коде, где эта обертка используется. контроллер, например команда. пользователь жмет кнопку, и контроллер проверяет, например, заполненность всех обязательных полей, и после обращается к модели. не вижу смысла использовать данный подход.
31. Гуков Ярослав (for_sale) 192 13.10.17 20:55 Сейчас в теме
(22) Любая библиотека, вызов, обёртка потребует доработки, если вызываемое изменится, не думаю, что это - минус именно данного подхода. Данный подход призван как раз собрать наиболее рисковые на замену места в одном месте, чтобы было ясно, что и где менять в случае чего. Более того, в случае, указанном в посте, когда функция
УправлениеКонтактнойИнформациейКлиент.ОткрытьФормуКонтактнойИнформации

изменилась в конфигурации, не потребовалось менять ничего в нашем модуле, кроме как раз области внешних вызовов, что уже доказывает, что в некоторых случаях описанные вами проблемы как раз неплохо решаются таким подходом.
23. Виталий Попов (Сурикат) 151 13.10.17 11:43 Сейчас в теме
Соглашусь с предыдущим высказыванием
Автор еще и неправильно назвал шаблон. Это не MVC, это обычный фасад.

А MVC нужно, когда у вас есть форма, которая объединяет данные несколько документов, как-то их собирает, что-то меняет и еще в какие-то регистры сведений пишет, к примеру. Вот тогда вы от использования MVC выиграете в долгосрочной перспективе.

Наверняка, все согласятся, что такое следует использовать только в крайних случаях при жестких требованиях к интерфейсу
VladimirL; +1 1 Ответить
32. Гуков Ярослав (for_sale) 192 13.10.17 21:21 Сейчас в теме
(23)

Ну я же специально вставил ссылку на википедию - почитайте вначале, что есть MVC, погуглите, а потом приходите авторитетно пинать автора.

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

На деле любая форма документа, отчёта, справочника должна писаться с мыслью об MVC. Чтобы, меняя интерфейс, не лезть в базу, и чтобы меняя базу. не лезть в интерфейс. И всё, никакой магии.

Пример 1:

#Форма
Процедура ОбработчикНажатияНаКнопкуПодборНоменклатуры()

	Запрос = Новый Запрос;
	// запросом выбираем остатки номенклатуры,
	// пришиваем к ним штрихкод из регистра
	
	Цикл...
	// обходим номенлатуру, чистим то, что уже было добавлено или ещё какие проверки

КонецПроцедуры
Показать


Пример 2:

#Форма
Процедура ОбработчикНажатияНаКнопкуПодборНоменклатуры()

	ТоЧтоНужно = ПолучитьНоменклатуруСОстаткамиИШтрихкодомИАртикулом();
	
	ОчиститьДубли(ТоЧтоНужно);

КонецПроцедуры

#Какой-то общий модуль или модуль менеджера
Функция ПолучитьНоменклатуруСОстаткамиИШтрихкодомИАртикулом()
...
Показать

Первый код - это говнокод. Когда изменится регистр остатков, когда остатки нужны будут не из Свободных остатков, а из остатков организации, когда нужно будет заменить параметр Дата или ещё что-то, что влияет на запрос в базу данных, нужно будет лезть в форму (интерфейс) и менять.
Второй пример - MVC. Есть интерфейс, который знает, что где-то есть номенклатура с остатками и штрихкодом, и работает с этими данными. Как эти данные получены - интерфейсу наплевать. Когда штрихкод начнут хранить не в регистре, а в справочнике Номенклатура, а остатки получать из текстового файлика где-то на хостинге, а не из базы - интерфейс будет спокойно работать в штатном режиме.

При чём тут строгие требования к интерфейсу? Я за критику, но конструктивную. Критика ради критики, даже не разобравшись в терминах - это уже деструкция и описанное выше ЧСВ, извините за резкость.
40. Виталий Попов (Сурикат) 151 14.10.17 00:46 Сейчас в теме
(32)

Возможно я резко выразился, за что приношу извинения.
Про то что у вас MVС или не MVC вопрос спорный. Чем MVC отличается от адаптера? Я считал, что MVC должен перенаправлять вызовы к разным моделям, в зависимости от параметра клиента. Если так, то MVC у вас только в случае с изменением семантики метода. Все остальное адаптер.

Сильное изменение параметров метода = ошибка компиляции, сами же об этом писали. Следовательно у вас нет вызова разных моделей, а вы заменяете один метод на другой, пусть и завернутый в стандартизованный интерфейс => адаптер.

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


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

Некоторые и модель не пишут, получая проблемы второго вашего примера (из комментария). Там вы как раз описываете случай изменения БД, которые не влияют на остальное приложение, т.к. у нас есть модель!

MVC нужен, когда у вам нужно выбирать модели и управлять их действиями. Но в простых случаях это делает платформа.
24. Maxim Kolkin (the1) 284 13.10.17 12:08 Сейчас в теме
А клиентские и серверные методы тоже в один модуль выносишь?
25. Валерий Крынин (shmalevoz) 111 13.10.17 12:12 Сейчас в теме
Заходили дальше. Только выносили функциональное различие в обработки, а в общем модуле оставляли общий интерфейс с вызовом подходящей обработки. Ну и назвали обработки не контроллерами, а адаптерами.
for_sale; +1 Ответить
36. Гуков Ярослав (for_sale) 192 13.10.17 21:45 Сейчас в теме
(25) Надо писать об этом посты и просвещать народ.
26. Павел Одинцов (Darklight) 13.10.17 12:20 Сейчас в теме
Увы. решение не полное. Так как помогает (и даже не автоматизирует, оставляя кучу ручных действий) убрать только один самый верхний уровень проводов. Да, он большой, но, всё же, лишь менее четверти всех проводов глубже никуда не пойдут. А остальные дальше всё равно уйдут в недра БСП и выдирать всё равно придётся вручную.

Да и замораичитваться с такими областями придётся постоянно - в разных модулях - дублируя их части многократно и хаотично.

Лично я давно, в своих разработках, пытаюсь освоить практику создания отдельного набора из нескольких общих модулей, который будет посредником для осуществления вызовов функций БСП из основного кода. Во-первых - не нужно многократно дублировать такую прослойку в местах применения, во-вторых в одном месте видно всё то, что используется из БСП, в-третьих - в этом же одном месте можно организовать ветвление поддерджки разных версий БСП и платформы. А в пятых.... об этом ниже.

В пятых - этого не достаточно. Нужна ещё и автоматизация.
В принципе это не так сложно (но лично я ещё этого не сделал) написать простую обработку текстовых модулей на предмет рекурсивного поиска вложенных вызовов методов модулей, автоматического выдергивания их и переноса в результирующую сборку - т.е. трассировка проводов от клемы до клемы и полный перенос используемой схемы.
При усложнении можно анализировать и некоторые блоки ветвления на предмет некоторых особых условий и переносить или не переносить те или иные ветви и, соответственно, вызовы.
Переносить можно как в отдельные модули (не типовые), так и осуществлять сверку с уже интегрированной версией БСП и не переносить то, что уже и так есть. Ну и проверять порядок и количество параметров у синхронизируемых методов БСП тоже можно.
Можно сделать настройки какие методы вообще не переносить - и ремить их вызовы или заменять на другие вызовы - например на свои методы, а какие наоборот - всегда переносить (даже если на них нет вызовов).

Вот это было бы хорошее решение.

Аналогично можно автоматизированно строить и модули-переходники - сначала в местах конечного использования писать обычные вызовы из БСП, а потом автоматизирванно заменять их на вызовы через модули-переходники с их же автоматическим заполнением.
zqzq; for_sale; +2 Ответить
33. Гуков Ярослав (for_sale) 192 13.10.17 21:28 Сейчас в теме
(26)
В принципе согласен с вами. На полноту и не претендовал, в 1С только нырни - всю жизнь оптимизировать можно:)
По вашему решению - если напишите развёрнутый пост, почитаю с интересом, если какие-то готовые идеи есть с примерами. За конструктивную критику - спасибо с плюсом.
39. Котэ Пруидзе (kote) 466 13.10.17 22:17 Сейчас в теме
(26)
Посмотрите на https://infostart.ru/public/591496/ - с точки зрения организации кода в объекты с относительно-нормальными интерфейсами в 1С.
В принципе то, что там сделано - с помощью процедурно-1С-стиля сделать невозможно. Т.е. такой способ даёт некоторые доп. возможности не только в организации кода, но бонусы в построении объектных ээ... пусть будет - абстракции.
27. Павел Одинцов (Darklight) 13.10.17 12:32 Сейчас в теме
А по поводу применимости паттерна MVC в 1С - в принципе вполне возможно было бы, хоть и есть некоторые трудности и непривычности. Главное это то, что 1С Предприятие 8 не поддерживает создание произвольного количества модулей внутри прикладных объектов. Конечно, с появлением модуля менеджера ещё можно как-то выкручиваться, но.... тут вторая дилемма, из двух проблем:
- Либо (когда строго примененяется) паттерн MVC в большинстве прикладных объектов попросту не нужен - иначе это попросту приведёт к излишнему усложнению
- Либо (когда действительно у объекта есть несколько форм представления) попросту будет сильно перегружать модуль менеджера дополнительным кодом

Эти проблемы, конечно, можно считать надуманными и в целом MVC вполне можно применить в 1С как в УФ, так и в управляемых формах, только, вот моды, нет, были бы хотя бы некоторые популярные типовые решения построены по MVC - так и развитие быстро бы начало набирать обороты. Но, компания 1С, видимо не видит в этом смысла. А жаль... Удобно было бы верстать УФ как текстовые макеты, переключаясь в визуальный редактор, отдельно от кода, который был бы размещён в отдельных модулях, с минимальными повторениями функционала.

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

Эх.... ждём 1С: Предприятие 9, авось...
kote; for_sale; CyberCerber; +3 Ответить
54. Вадим . (tindir) 17.10.17 11:04 Сейчас в теме
(27) Частияно Шастье наступит с приходом EDT(верстка текстом). А вот о формировани "Шапки" документа одинаково для всех тоже давно мечтается. Как у C#MVC header.cs в котором описан основной шаблон для нужных тебе объектов. Но есть всегда НО.
28. Алексей Рожнятовский (spetzpozh) 13.10.17 12:53 Сейчас в теме
Насчет версий БСП. БИТ в их БИТ:Финансе пошел дальше и внедрил в типовое решение ЕЩЕ одну БСП со своими префиксами бит_. С одной стороны много сил на копирование, с другой - тебя не парит, что происходит со встроенной БСП. Речь про БИТ Финанс для БП 2.0.
Возможно, в 3.0 они это убрали.
29. Алексей Иванов (IvanovAV) 42 13.10.17 17:17 Сейчас в теме
Иногда, проще свой простенький код и запрос написать, чем завязываться на общие модули типовой конфы и БСП. Она сама по себе, а мы сами по себе. Самое обидное когда начинают бестолково Имена объектов и реквизитов переименовывать, в частности УТ 11. Вопрос: для чего им синонимы?
34. Гуков Ярослав (for_sale) 192 13.10.17 21:31 Сейчас в теме
(29) Если 1С перестанет что-то постоянно бестолково делать, оно потеряет свою самобытность :)
IvanovAV; +1 Ответить
38. Котэ Пруидзе (kote) 466 13.10.17 22:08 Сейчас в теме
(27)
.. помню, еще в 2010 году как https://infostart.ru/public/74872/

Короче, все эти паттерны в мире 1С - это как метание биссера.

А на счёт зависимостей от функций в БСП выход простой.. берите и копируйте себе в обработку нужную функцию.
А лучше - напишите свою. Окупится в течении 1 года поддержки.

Кто там про вечную альфу сказал - хлопаю стоя. Но всё это от того, что язык не развивается.. а ведь есть куда и как.
Вот, например, люди чудят - и ведь работает - https://github.com/covrom/gonec/issues/5#issuecomment-335707925

А 1С - рано или поздно сойдёт на нет.. потому, как глупое заявление на конференции топа 1С, что "в ERP 5 млн. строк кода" когда то будет встречено заявлением "а в нашем - всего 50 тыс. - но делает все то же самое"..
neikist; IvanovAV; pm74; +3 Ответить
41. Алексей Иванов (IvanovAV) 42 14.10.17 02:31 Сейчас в теме
(38) По заявлению топа, стало понятно: Что если качество продукта они оценивают количеством строк кода, следовательно зарплату в 1С за это и платят. Теперь понятно почему в новых типовых конфигурациях куча промежуточных процедур состоящих из одной строчки перебрасывающей в другую процедуру.
Интересно какая взаимосвязь между количеством критических ошибок и строк кода? Даже страшно представить сколько их в 5 млн строк кода.
42. Игорь Фелькер (Brawler) 328 14.10.17 12:47 Сейчас в теме
(41) Без разницы какое число кода у них там, все упирается на самом деле в качество этого кода.
Я вон вчера ковырялся в коде КА 2.4.1.215, разбирался как цена в документе рассчитывается и набрел на кусок кода, где определяется есть ли колонка в таблице или нет с определенным именем.
Переменная "ТабличнаяЧасть", тип значения "ДанныеФормыКоллекция".
В двух местах общего модуля это дело встречается, в одной функции и исполняется последовательно одно за другим.
Как-то так упрощенно
....
ЕстьКоличествоУпаковок = ТабличнаяЧасть.Выгрузить().Колонки.Найти("КоличествоУпаковок") <> Неопределено;
....
....
ЕстьКодСтроки = ТабличнаяЧасть.Выгрузить().Колонки.Найти("КодСтроки") <> Неопределено;
....

Что происходит?
Так как у объекта типа "ДанныеФормыКоллекция" нет возможности узнать какие колонки в таблице есть, то 1С пользуется возможностью и выгружает таблицу посредством "Выгрузить()" в ТаблицуЗначений, а там уже есть возможность получить доступ к колонкам, чем они и пользуются "Колонки.Найти...", однако при таком использовании "Выгрузить()" делается полная копия таблицы как я понимаю, идет жор памяти + ресурсов ЦП. Да в основном незначительно, на мелких документах, но на больших это уже будет хуже, а при большом числе юзеров так вообще...
Пишу на линию службы поддержки, и указываю им на данную ситуацию и пишу простейший выход из ситуации.
....
ЕстьКоличествоУпаковок = ТабличнаяЧасть.Выгрузить(Новый Массив()).Колонки.Найти("КоличествоУпаковок") <> Неопределено;
....
....
ЕстьКодСтроки = ТабличнаяЧасть.Выгрузить(Новый Массив()).Колонки.Найти("КодСтроки") <> Неопределено;
....

Кто глазастый заметил уже "Выгрузить(Новый Массив())", просто получить структуру таблицы без строк данных. Жора памяти нет, ЦП тоже радуется.
Но там со стороны 1С начинается, а где падает производительность?, а как воспроизвести?, а замеры времени делали? ну жесть... ладно второй вопрос еще куда не шло правильный, но другие... Хотя и второй вопрос могли не задавать ибо четко указал, где есть проблема и они сами должны знать, когда программа туда попадает.
43. Котэ Пруидзе (kote) 466 14.10.17 21:10 Сейчас в теме
(42) RE "(41) Без разницы какое число кода у них там.."
Это заблуждение. Разница есть. Примерно в 100 раз.. (5 000 000/50 000)
И думаю, что "плотность" ошибок в 5 млн. будет выше (и сохраняться они дольше) - хотя бы в силу того, что отрабатывать каждый участок будет в среднем в 100 раз реже..
44. Игорь Фелькер (Brawler) 328 14.10.17 21:47 Сейчас в теме
(43) сейчас у вас 50 000 взяты с потолка и никогда эти 50 000 не сравнятся и близко даже с 1 000 000 строк кода
Дурные варианты сравнения, где весь модуль записан в одну строку не рассматриваем.
45. Котэ Пруидзе (kote) 466 14.10.17 21:55 Сейчас в теме
(44) Попробуйте python и его стандартную библиотеку. Разница будет в 200 раз.
47. Игорь Фелькер (Brawler) 328 15.10.17 00:57 Сейчас в теме
(45) не то сравниваете, вы уже на уровень платформ спустились грубо говоря.
python и его стандартную библиотеку
1С и его стандартную библиотеку (платформа)!
C# и его стандартную библиотеку
...

И чего их сравнивать?
Нужно готовые решения созданные на их базе сравнивать!!!
for_sale; +1 Ответить
49. Павел Одинцов (Darklight) 16.10.17 14:57 Сейчас в теме
(38)
А на счёт зависимостей от функций в БСП выход простой.. берите и копируйте себе в обработку нужную функцию.
А лучше - напишите свою. Окупится в течении 1 года поддержки.

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

То что идея с БСП у 1С не оправдала ожиданий - это факт - и с каждой редакцией БСП это всё только усугублдяется и запутывается! Особенно на фоне попытки компании 1С реализовать в БСП на процедурном языке нечто подобие ООП и распределения функционала по куче подсистем, которые могут то быть, а то и не быть в результирующем решении. Реализована БСП умозакрутительно ужасно! Нужен полный пересмотр концепции БСП. Но... наверное ранее 1С: Предприятие 9 ждать не придётся. Нужна замена БСП на БСБ (BSL): Библиотеку стандартных библиотек - ох... тафталогия получилась.

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

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

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

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

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

Ну и, соответственно, такие библиотеки бы не засоряли само решение. Пусть и хранились бы в конфигурации (для обычного конфигуратора), но их состав не отображался бы на прямую в дереве конфигурации. А при работе через EDT вообще они будут отделенными проектами - и собираться в итоговую конфигурацию ИБ будут из отдельных папок. Соответственно, и обновляться они тоже должны отдельно и не зависимо.

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

Вот это было бы круто! Даст 1С.Бог... когда-нибудь увидим такое.


Впрочем, и без компании 1С это всё можно было бы сворганить на EDT - просто нужен соотвествующий плгаин для расширения Eclipse - чтобы он мог поддерживать отдельные проекты (библиотеки) - как специально интегрируемые в конфигурацию ИБ. Ну и контроллировал их зависимости. Ну а интеграция в ИБ шла бы уже специально сгенерированными общими модулями - а места использования в алгоритмах - отдельно бы пдправлялись, чтобы пути вызова были правильными!

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

Такой подход и Расширения 1С бы свёл на нет - уж больно они корявые вышли!

Так что это можно было бы сделать, скажем уже в 1С Предприятие 8.4 (хотя нет, в 8.4 уже не успеют - тогда в 8.5), и довести до ума к 8.6 - 8.7 :-D лет так через 20
8-|
52. Котэ Пруидзе (kote) 466 17.10.17 09:04 Сейчас в теме
(49)
Можно сказать проще - в 1С не хватает возможностей подключения библиотек в стиле нормальных языков программирования и менеджера управления зависимостями с нормальной системой версионирования.

Все проблемы с БСП растут отсюда.

.. а так было бы:


БСП_23 = Подключить("БСП.v.2.3");
БСП_24 = Подключить("БСП.v.2.4");

_стр = БСП_23.СтроковыеФункции;
_хмл= БСП_24.РаботаСXML;

мМассив = _стр.МассивВСтроку(вхМассив);

мХМЛ = _хмл.СериализоватьСсылку(вхДокументСсылка);

Показать


.. код бы не ломался, когда появляется новая БСП, но нужны оттуда новые фукнции
53. Павел Одинцов (Darklight) 17.10.17 10:13 Сейчас в теме
(52)Да. Лишь по вашему примеру примечание: у Вас там описано динамическое связывание - вещь безусловно хорошая, но статическое связывание применяется чаще (как и то, что решение редко применяет разные версии БСП), примерно как сделано в 1Script

//Где то в настройка дерева конфигурации, в группе "Общие.Библиотеки" создана ветвь-узел: БСП, в ней ветвь-лист  "Ядро", где статически подключена некоторая  реализация БСП.Ядро
//Причём либо одна конкретная версия (которая будет связана с именем "БСП.Ядро", либо набор версий, где лишь одна будет назначена основной - на использование по имени без указания версий (по умолчанию)

//Вариант1
#Использовать Библиотеки.БСП.Ядро;
//Для набора версий можно уточнить версию
//#Использовать Библиотеки.БСП.Ядро("2.4.*.*");
//Такая конструкция подключит БСП определённой версии ко всему модулю (но только в его границах)

//Вариант2
//А такая конструкция сделает библиотеку доступной только в определённой области; причём, версия библиотеки будет выбрана не ниже заданной версии: 2.3.8.0 но ниже, чем 2.4, с выбором максимальной доступной версии БСП: так <2.3.8<.* с выбором минимальной доступной)
#Использование Библиотеки.БСП.Ядро(">2.3.8<.*") 

_стр = СтроковыеФункции; //редакции 2.3: получение общего модуля из библиотеки БСП.Ядро(">2.3.8<.*")

//Вариант3
_хмл= Библиотеки.БСП.Ядро("2.4.3.0<").РаботаСXML; //Прямое обращение  к общему модулю библиотеки БСП.Ядро нужной версии 2.4.3.0<

мМассив = _стр.МассивВСтроку(вхМассив);

#КонецИспользования //Библиотеки.БСП.Ядро(">2.3.8<.*") 

//здесь _стр уже не доступно
//здесь _хмл продолжает быть доступным

мХМЛ = _хмл.СериализоватьСсылку(вхДокументСсылка);
Показать


Ну, может я всё слишком усложняю, применение Варианта1 уже вполне было бы хорошо, как и Варианта3, как и вашего варианта с динамическим связыванием, хотя может, Вы как раз имели в виду мой Вариант3.
46. Monkey Coder (yurii_host) 1260 14.10.17 22:09 Сейчас в теме
Я тоже давно использую мвц в 1с при написании обработок. Я этот принцип понимаю, как отделение интерфейса от бизнес логики (представления от модели). Поэтому я все процедуры, которые обращаются к базе описываю в модуле обработки, а все процедуры, которые работают с интерфейсом - в форме. В качестве контроллера использую короткие серверные процедуры (тоже в форме). Получается что-то типа того:

&НаСервере
Процедура ОбновитьЦеныНаФорме() // контроллер

	АктуальныеЦены = РеквизитФормыВЗначение("Объект").ПолучитьАктуальныеЦены(Параметры); // модель
	
	ВывестиТаблицуЦенВТаблицуНаФорме(АктуальныеЦены); // представление

КонецПроцедуры


Также хорошо подходит при печати. Например, так:

Процедура ПечатьЗаказа(Заказ) // контроллер

	ДанныеДляПечати = ПолучитьДанныеЗаказаДляПечатиЗапросом(Заказ); // модель
	
	СформироватьПечатнуюФормуЗаказа(ДанныеДляПечати); // представление

КонецПроцедуры


Примеры придумал на ходу, но принцип использую такой
48. Гуков Ярослав (for_sale) 192 16.10.17 12:10 Сейчас в теме
(46)
РеквизитФормыВЗначение("Объект")

Вообще хорошо, только РеквизитФормыВЗначение("Объект") - вариант так себе, оно его каждый раз будет заново получать, а если что-то инициализируется в модуле, то ещё хуже, каждый раз по-новой. Лучше использовать модуль менеджера.
50. Павел Одинцов (Darklight) 16.10.17 15:15 Сейчас в теме
(48)Думаю, этот подход подразумевает статичность объекта - т.е. все такие вызовы функций - являются статическими и не хранять промежуточных значений где -либо ещё, кроме передаваемых параметров.

Кстати, если в общих модулях конфигурации реализовать механизм кеширования - то этот значение объекта можно было бы закешировать где-нибудь (на время сеанса / ~20 мин) - и получать его от-туда по кеш-ключу) - но это тоже не без недостатков.
Но я бы, всё же, использовал тут не модуль объекта, а модуль менеджера. Одна беда - у внешних обработок/отчётов его нет (тут дальше следуют много заценгзуренного мата в сторону разработчиков 1С 8 из компании 1С). К модулю менеджера в серверном контексте можно просто обращаться по прямому пути (Документ.Такойто.КакаяТоФункция(ЭтаФорма)). Ну, при желании можно и более универсально (Выполнить(Метаданные().ПолноеИмя()+"."+"КакаяТоФункция(ЭтаФорма)")).

А вообще применение MVC в 1С УФ усложняется как раз раз тем, что в управляемых формах есть разделение контекста на "Серверный" и "Клиентский". Причём и тот и другой ещё делиться на "Без контекста формы" и "С контекстом формы". И именно в этом контексте формы вся сложность - т.к. он доступен только в модуле самой формы - но, это тоже решаемо - обычно вполне достаточно в него на форме войти и передать уже внешней функции в качестве переменной ЭтаФорма (что компания 1С и очень часто делает в своих прикладных решениях - т.е. уже отчасти применяет MVC - жаль только, что отчасти).

С разделением контекста на "Серверный" и "Клиентский" тоже есть проблема - увы, но в клиентском контексте не доступны ни модуль объекта (включая внешние и встроенные обработки), ни модуль менеджера. То есть - чтобы вынести клиентские реализации обработчиков из формы - нужно создавать встроенный в конфигурацию отдельный ОбщийМодуль с доступным клиентским контекстом выполнения. Что отделяет реализацию от принадлежности к самому объекту приложения, и требует размещения в составе конфигурации. Некрасиво и неудобно получается. И поддержку сильно усложняет.
51. Monkey Coder (yurii_host) 1260 16.10.17 20:43 Сейчас в теме
(48)
(50) Да, именно потому и использую модуль объекта, чтобы можно было отлаживать в том числе и в виде внешней обработки. Пускай не очень красиво, но зато практично. Более удобного варианта я не нашел.
Когда-то делал замеры того, сколько выполняется РеквизитФормыВЗначение("Объект"). Создал обработку с табличной частью 10 колонок на 1000 строк и выполнял эту процедуру в цикле. Получалось около 10 циклов в секунду, т.е. накладные расходы около 0.1 сек. Замеры выполнял на файловой базе. Но на серверной должен наверное быть похожий результат, т.к. действие уже выполняется на сервере и обращения между клиентом и сервером при этом не происходит. Тем более, что на практике в цикле эту операцию выполнять нет необходимости, обычно достаточно один раз получить объект из реквизита формы. Такую задержку пользователь не ощущает, а удобство доработки заметно возрастает.
В форме обычно описываются простые процедуры по работе с интерфейсом. Они маленькие, но их очень много. А в модуле описывается работа с запросами. Первая часть меняется реже, да и переходить по процедурам проще из самой формы, а вторая часть меняется постоянно на первых порах. В модуле проще и быстрее находить нужные методы. Плюс избавляет от спагетти, когда выполнили запрос, при этом подставили какие-то реквизиты с формы, и сразу же обходим результат и меняем оформление, сбрасываем модифицированность и т.д.
56. Артём Андриянов (CSiER) 17.10.17 18:03 Сейчас в теме
На самом деле MVC я здесь задел "по касательной", как одно из воплощений идеи о том, что для упрощения поддержки и интеграции внешнее взаимодействие лучше вынести в ту самую прослойку - Контроллер.

Посыл изучать паттерны (шаблоны) - отличный. Все мы рано или поздно приходим к некоторым решениям, а потом оказывается, что они уже давно существуют в виде известных паттернов/антипаттернов. В контексте 1С не хватает хороший статей по best practice применения шаблонов проектирования (если знаете - просьба оставить в комментарии или в личку). Может быть когда-нибудь и появится адаптированная версия GOF для 1С :)
Оставьте свое сообщение