Версия для печати темы (https://pro1c.org.ua/index.php?s=9762fac32e309177e05b1fcc4b69401e&showtopic=54934)

Нажмите сюда для просмотра этой темы в обычном формате

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 _ Тематическое общение _ Говнокод или нет?

Автор: Vofka 30.10.19, 9:49

Тема создана по мотивам https://pro1c.org.ua/topic/kak-v-vyborke-rezultata-zaprosa-sravnit-znachenievalyutadokumenta-54891/ темы.

Итак, есть задача: нужно определить, что валюта в документе - доллар. Было предложено пару вариантов:

1. Если ВалютаДокумента = справочники.Валюты.НайтиПоКоду(КодДоллара) Тогда
2. Если ВалютаДокумента.Код = КодДоллара Тогда

Так же было высказано мнение, что подобные конструкции - это ковнокод. Тема, на мой взгляд, довольно интересная и можно было бы поговорить на эту тему.
Как вы считаете:
1. Говнокод ли это?
2. Говнокод ли это конкретно в такой задаче?

Настоятельная просьба при обсуждении не переходить на личности!

Я проголосовал за вариант "Оба варианта нормально". Соглашусь с комментарием из темы источника, что код валюты это достаточно стабильный показатель, на который можно ссылаться в большинстве случаев. Но если бы я писал какое-то тиражируемое решение, то так, возможно, не сделал бы. Но в обычных внутренних системах, считаю, что это вполне допустимо. Раньше на каждый подобный чих я всегда заводил константы, потому что везде написано, что делать так плохо и надо это выносить в константы. То, что в идеале так должно быть, тут я не спорю. Но мы работаем не в идеальных условиях и когда список констант переваливает за пару сотен и ты начинаешь добавлять дублирующие константы, потому что уже не в состоянии проинспектировать все, начинаешь писать НайтиПоКоду и прочее crazy.gif

Автор: nik389 30.10.19, 9:54

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

Автор: denis84 30.10.19, 10:50

Оба варианта имеют право на жизнь. Т. к. на мой взгляд поиск по коду оптимально решает поставленную задачу.

Автор: Petre 30.10.19, 11:16

В общем и целом следует избегать обоих конструкций.

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

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

Автор: onsamuy 30.10.19, 11:29

Вполне корректное решение и №1 и №2. Но вопрос в том что если база упр, то возможно что код валюты им побоку. Я бы просто в спр. Валюты создал предопределенные для основных валют - usd eur uah. Тогда проверка организовывается без проблем. Ну а если конфа например какой то фин. группы, где валют десятки smile.gif))) ? Ну тогда все по старому - мВалютаУправленческогоУчета smile.gif))))))))))))))))). Да и вообще сейчас идет тенденция все завязывать на БСП.

Автор: TipsyKID 30.10.19, 12:42

Как по одной строчке, без контекста, можно понять говнокод это или нет?

Все упирается в то, что такое КодДоллара и где / как оно определяется и самое главное для чего?
В контексте этого, проверки на доллар а потом умножения на 24, СуммаС = Выборка.СуммаДокумента * 24 является плохим стилем программирования.

Нет строго понятия, что такое гавнокод, но есть множество книг на тему хорошего кода (Например "Чистый код" Роберта Мартина).

Представим, что, через некоторое время у клиента появся расчетные счета не только в долларах, но и в Евро, а еще через некоторое время в Юанях.

Считаете ли Вы, что корректна будет проверка:

Если Выборка.ВалютаДокумента = Справочники.Валюты.НайтиПоКоду(КодДоллара) Тогда
     СуммаС = Выборка.СуммаДокумента * 24;
ИначеЕсли Выборка.ВалютаДокумента = Справочники.Валюты.НайтиПоКоду(КодЕвро) Тогда
     СуммаС = Выборка.СуммаДокумента * 31;
ИначеЕсли Выборка.ВалютаДокумента = Справочники.Валюты.НайтиПоКоду(КодЮаня) Тогда
     СуммаС = Выборка.СуммаДокумента * 3.5;
Иначе
  //...
КонецЕсли;

ИЛИ
Если Выборка.ВалютаДокумента.Код = КодДоллара Тогда
     СуммаС = Выборка.СуммаДокумента * 24;
ИначеЕсли Выборка.ВалютаДокумента.Код = КодЕвро Тогда
     СуммаС = Выборка.СуммаДокумента * 31;
ИначеЕсли Выборка.ВалютаДокумента.Код = КодЮаня Тогда
     СуммаС = Выборка.СуммаДокумента * 3.5;
Иначе
  //...
КонецЕсли;


Лично для меня, вопрос стоит именно так.

Автор: Vofka 30.10.19, 13:36

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

Цитата(TipsyKID)
То, что Вы посоветовали, начинающему программисту :
Если Выборка.ВалютаДокумента = справочники.Валюты.НайтиПоКоду(КодДоллара) Тогда

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

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

Автор: sava1 30.10.19, 13:43

давайте отвлечемся от конкретной конфигурации и предположим, что это код из внешней печатной формы для НЕИЗМЕНЕННОЙ конфигурации.

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

Автор: Vofka 30.10.19, 14:08

Цитата(sava1 @ 30.10.19, 13:43) *
п.с. По "чистому коду" - программер на С++ весь 1С-кий код назвал бы "Овном" - потому, что нигде объект принудительно не разрушается, а рассчитывать на "уборщик" - плохой стиль (да и опасно)

Программера на C++, который не читал не одной книги по 1С, но полез туда что-то править - надо подсрачниками от конфигуратора отгонять. То же справедливо и по отношению к "чистому" 1С-нику, который ничего не читал по C++, но говорит о том какое это говно.

Автор: Petre 30.10.19, 14:19

С точки зрения программиста С++ тут вообще не о чем говорить. Язык 1с - ни разу не ООП, и мнение программиста С++ будет как минимум необъективным.
Но, кроме общепринятых правил (универсальных для большинства языков), есть "официальные" рекомендации, например, т. н. "Система стандартов и методик разработки конфигураций для платформы 1С"...

TipsyKID @ Today, 12:42 * ,
Магические константы - однозначно говнокод. Но в данной теме, как я понимаю, не об этом...

Автор: zfilin 30.10.19, 14:30

Мне не нравятся оба варианта.

Первый тем, что для каждой строки выборки будет осуществляться поиск по справочнику.
Если вынести поиск ЗА цикл обхода выборки, то такое решение вполне нормально.
Ссылка сравнивается со ссылкой, все хорошо.
(если в запросе гарантировано одна строка, например потому что выборка определена как ПЕРВЫЕ 1, то этот вариант подходит и в таком виде).

Второй вариант плох тем, что идет обращение к реквизиту переменной ссылочного типа через точку. Что порождает лишний запрос к базе (опять же в цикле).
Его следовало бы переделать и еще в запросе выбрать что-то типа: "Валюты.Код КАК КодВалюты" и уже в условии сравнивать его с кодом доллара.

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

Автор: Vofka 30.10.19, 14:52

zfilin, суть темы/опроса: приемлемо ли найти валюту таким образом. То есть вопросы поиска в цикле немного за рамками данного обсуждения.

ПС. убрал слово Выборка в вариантах, что бы не смущало.

Автор: pablo 30.10.19, 14:55

Проголосовал за второй вариант, поскольку он отработает как на сервере, так и на клиенте(любом), а второй вариант уместен только для сервера и толстого клиента.

Автор: Макс1С 30.10.19, 15:23

Оба варианта норм.
В частности для валюты код является уникальным не в рамках 1С, а по классификатору, который можно считать константой.
Для самописных баз или где пользователи совсем безответственные это накладывает ряд рисков что код валюты доллар будет не 840.
Так что норм использовать код валюты в качестве локальной переменной или константы в процедуре/форме/объекте.
Сам натыкался на базы с 300+ добавленными константами, назначение 80% из которых никто не помнит

Автор: stark 30.10.19, 15:47

Цитата(Макс1С @ 30.10.19, 16:23) *
Сам натыкался на базы с 300+ добавленными константами, назначение 80% из которых никто не помнит

Как вариант справочник с реквизитом типа: ЛюбаяСсылка, Булево, Строка. В нем предопределенные элементы.

Автор: zfilin 30.10.19, 16:10

Vofka @ Сегодня, 14:52 * ,
А. Ну тогда пофигу. Оба варианта норм, но второй мне нравится больше.

stark @ Сегодня, 15:47 * ,
Жуть.
Кто-нибудь воткнет этот справочник в запрос рано или поздно и начнется...
Я бы избегал использования составных типов в случаях, когда их можно не использовать.

Автор: Макс1С 30.10.19, 16:23

stark @ Сегодня, 15:47 * ,
пробовали, суть не меняется - куча предопределенных элементов, назначение которых становится загадочным через какое-то время

Автор: TipsyKID 30.10.19, 16:52

Цитата(Vofka @ 30.10.19, 14:36) *
в исходной теме спор возник, как я понял, на тему того как определить валюту


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

Цитата(Vofka @ 30.10.19, 14:36) *
мы же даже не знаем есть ли в системе регистр курсов валют


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

Автор: fly 31.10.19, 11:31

Цитата(Vofka @ 30.10.19, 10:49) *
Итак, есть задача: нужно определить, что валюта в документе - доллар. Было предложено пару вариантов:

1. Если ВалютаДокумента = справочники.Валюты.НайтиПоКоду(КодДоллара) Тогда
2. Если ВалютаДокумента.Код = КодДоллара Тогда


в первом варианте происходит поиск по всему справочнику, и понятно - что валюты чаще всего небольшой справочник - и поиск происходит быстро.
если применять для справочников Номеклатура, или Контрагенты - где может 10-15-20 тыс. то уже производительность может снижаться.

+ в этом варианте, это вероятнее всего должно выполняться непосредственно на сервере, т.е. обращение к серверу идет.

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

fly @ Сегодня, 12:19 * ,
как по мне, 2й вариант с точки зрения обращения к серверу, и места использования все же предпочтительней.

Автор: Petre 31.10.19, 11:32

QUOTE (fly @ 31.10.19, 11:19) *
во втором варианте непосредственно проверяется "свойство элемента" (если правильно называю), то нет обращения к серверу и перелистать весь справочник, и найти и потом сравнить + выполнение будет где угодно работать, потому как уже получена при открытии вероятнее всего валюта.

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

Автор: Vofka 31.10.19, 12:02

fly, что первый, что второй вариант - это запрос, который ищет элемент справочника по коду. smile.gif

Автор: fly 31.10.19, 14:02

Цитата(Vofka @ 31.10.19, 13:02) *
что первый, что второй вариант - это запрос, который ищет элемент справочника по коду.

отлично smile.gif
буду знать

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

fly @ Сегодня, 15:00 * ,
т.е. читабельности, еще других значений по сути так же нет отличий - так как обращение к объекту через точку, и метод найтипокоду - по логике легко воспринимаются любому, как неотъемлемая часть...

Автор: pablo 31.10.19, 14:15

Цитата
Обращение к объекту через точку - это, во-первых, сервер

1. Я согласен, что я не совсем корректно выразил свою точку зрения и указал что обращение через точку отрабатывает одинаково на сервере и клиенте.
2. Тем не менее для определенных ситуаций, а именно, когда объект является реквизитом формы, это вполне допустимо и работает быстрее, чем аналогичный код на сервере из-за отсутствия накладных расходов.

Автор: Vofka 31.10.19, 15:16

Цитата(fly @ 31.10.19, 14:02) *
т.е. я правильно понял, с точки зрения технической и тот и тот, по сути не имеют разницы?

Petre правильное замечание сделал:
Цитата(Petre @ 31.10.19, 11:32) *
с небольшой оптимизацией в виде кеширования свойств объекта после первого обращения

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

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua