gifts2017

Оформление и рефакторинг сложных логических выражений

Опубликовал Сергей Старых (tormozit) в раздел Программирование - Практика программирования

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

Возьмем для примера фрагмент кода из типовой бухгалтерии

Если ((НомерИзменяемойКолонки = "4") Или (НомерИзменяемойКолонки = "5"))
Или (((
НомерИзменяемойКолонки = "7") Или (НомерИзменяемойКолонки = "8")
И (
ГруппаРасчета = мИдГруппы7))) Тогда
    Расчет(ГруппаРасчета);
КонецЕсли;

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

Приоритеты логических операций

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

Методика И-ИЛИ дерева

Я же предлагаю сложные логические выражения оформлять в виде И-ИЛИ дерева. Под И-ИЛИ деревом я подразумеваю дерево, нетерминальные узлы которого представляют собой группы (последовательности) одинаковых логических операций И или ИЛИ, а терминальные - остальные логические выражения. Хорошим примером такого дерева является отбор настроек компоновки данных, правда у него верхняя (корневая) группа всегда имеет тип "И". В случае встроенного языка мы этим не ограничены и можем использовать любой тип верхней. В рассмотренном примере как раз сверху расположена группа "ИЛИ". Рассмотрим преобразование выражения примера к И-ИЛИ дереву.

1. Встаем на первую открывающую скобку и с помощью сочетания клавиш CTRL+] находим тело первого узла и переносим целиком в одну следующую строку с отступом относительно слова Если

Если
    ((
НомерИзменяемойКолонки = "4") Или (НомерИзменяемойКолонки = "5"))
Или (((
НомерИзменяемойКолонки = "7") Или (НомерИзменяемойКолонки = "8")
И (
ГруппаРасчета = мИдГруппы7))) Тогда

2. Следующий логический оператор будет И или ИЛИ. Он и определяет тип группы этого уровня при условии что все группы обрамлены скобками. Для повышения наглядности вставляем в начало группы операцию с не нарушающим результат вычисления группы константным значением (для И - ИСТИНА, для ИЛИ - ЛОЖЬ).

Если Ложь
    Или ((
НомерИзменяемойКолонки = "4") Или (НомерИзменяемойКолонки = "5"))
    Или (((
НомерИзменяемойКолонки = "7") Или (НомерИзменяемойКолонки = "8")
    И (
ГруппаРасчета = мИдГруппы7))) Тогда

3. Встаем на следующую открывающую скобку корневого уровня и повторяем шаг 1.

Если Ложь
    Или ((
НомерИзменяемойКолонки = "4") Или (НомерИзменяемойКолонки = "5"))
    Или (((
НомерИзменяемойКолонки = "7") Или (НомерИзменяемойКолонки = "8") И (ГруппаРасчета = мИдГруппы7))) Тогда

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

Если Ложь
    Или ((
НомерИзменяемойКолонки = "4") Или (НомерИзменяемойКолонки = "5"))
    Или (((
НомерИзменяемойКолонки = "7") Или (НомерИзменяемойКолонки = "8") И (ГруппаРасчета = мИдГруппы7)))
Тогда

5. Далее повторяем шаги 1-3 для всех вложенных узлов (условий в скобках). Следует заметить, автор оригинального выражения не все группы обрамил скобками и последние 2 оператора из числа образующих группы различны и не разделены скобками. В итоге получаем

Если Ложь
    Или (Ложь
        Или (
НомерИзменяемойКолонки = "4")
        Или (
НомерИзменяемойКолонки = "5"))
    Или (Ложь
        Или (
НомерИзменяемойКолонки = "7")
        Или (Истина
            И (
НомерИзменяемойКолонки = "8")
            И (
ГруппаРасчета = мИдГруппы7)))
Тогда

6. Теперь нам становится понятно, что логическое выражение можно упростить. Все вложенные однотипные (И или ИЛИ) группы можно смело всегда поднимать в родительскую группу.

Если Ложь
    Или (
НомерИзменяемойКолонки = "4")
    Или (
НомерИзменяемойКолонки = "5")
    Или (
НомерИзменяемойКолонки = "7")
    Или (Истина
        И (
НомерИзменяемойКолонки = "8")
        И (
ГруппаРасчета = мИдГруппы7))
Тогда

7. В таком виде уже можно довольно безопасно убрать скобки вокруг условий внутри строк. В итоге получаем

Если Ложь
    Или
НомерИзменяемойКолонки = "4"
   
Или НомерИзменяемойКолонки = "5"
   
Или НомерИзменяемойКолонки = "7"
   
Или (Истина
        И
НомерИзменяемойКолонки = "8"
       
И ГруппаРасчета = мИдГруппы7)
Тогда

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

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

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

 

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

С осторожностью ее можно применять и в языке запросов 1С. Осторожность здесь нужна потому, что лишние логические операции (Истина И, Ложь ИЛИ) в некоторых случаях могут привести к отказу СУБД использовать подходящие индексы.

Использую эту методику уже более 5 лет.

Плюсы:

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

Минусы:

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

Шаблоны

Для удобства написания сложных логических выражений по этой методике рекомендую добавить себе шаблоны

Условие с корневой группой "И" -

Если Истина
    И
Тогда
КонецЕсли;

Условие с корневой группой "Или"

Если Ложь
    Или

Тогда
КонецЕсли;

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Осипов Сергей (fixin) 21.09.12 10:36
а не проще ли для этого примера по другому?

Если ((НомерИзменяемойКолонки = "4") Или (НомерИзменяемойКолонки = "5"))
Или (((НомерИзменяемойКолонки = "7") Или (НомерИзменяемойКолонки = "8")
И (ГруппаРасчета = мИдГруппы7))) Тогда
Расчет(ГруппаРасчета);

Условие = НомерИзменяемойКолонки = "4";
Условие = Условие ИЛИ НомерИзменяемойКолонки = "4";
Условие2 = НомерИзменяемойКолонки = "8" И ГруппаРасчета = мИдГруппы7;
Условие = Условие ИЛИ Условие2;

Дешево и сердито, я лично перешел на такой способ.
Вместо Условие2 лучше писать осмысленный текст, тогда еще и комментирование происходит, например УсловиеГруппыОсобыхРасчетов.
Gasilin; su_mai; Rustig; brr; +4 Ответить 2
2. Сергей Старых (tormozit) 21.09.12 11:14
(1) В некоторых случаях такой подход действительно оправдан, но в большинстве случаев он излишне повышает "жесткость" логической конструкции.
3. Осипов Сергей (fixin) 21.09.12 12:03
(2) зато прозрачно и наглядно.
4. Игорь Steelvan (Steelvan) 24.09.12 21:55
В языке Дракон удобно визуализировать такие выражения.
Serg_1C(M); +1 Ответить
5. Владислав Мороз (vlad.frost) 26.09.12 00:56
Цель рефакторинга - сделать код более читаемым. А вот это вот "ЕСЛИ Ложь ИЛИ НомерИзменяемойКолонки = "4"" у меня уже выворачивает мозги наизнанку.

Я бы написал так:

ВыполнитьРасчетПоНомеруКолонки(ГруппаРасчета, НомерИзменяемойКолонки, мИдГруппы7); // Выделили метод

Процедура ВыполнитьРасчетПоНомеруКолонки(ГруппаРасчета, НомерИзменяемойКолонки, мИдГруппы7)

  Если НомерИзменяемойКолонки = "4" Или НомерИзменяемойКолонки = "5" Тогда
    Расчет(ГруппаРасчета);
    Возврат;
  КонецЕсли;

  Если ГруппаРасчета <> мИдГруппы7 Тогда // Инвертируем условие
    Возврат;
  КонецЕсли;

  Если НомерИзменяемойКолонки = "7" Или НомерИзменяемойКолонки = "8" Тогда
    Расчет(ГруппаРасчета);
  КонецЕсли;

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


Согласитесь, так читается ещё легче.
корум; Chernik; asf-trade; bdvtdviking; Tolpinski; iTony73; Rustig; +7 Ответить 1
6. Сергей Старых (tormozit) 26.09.12 01:19
(5) Возможно проблема только в адаптации мышления к элементарным приемам из булевой алгебры для тех кто с ней не знаком. Истина не меняет результат конъюнкции (ИСТИНА И), и Ложь не меняет результат дизъюнкции (ЛОЖЬ ИЛИ).
Обрати внимание, я не предлагал их записывать в одну строку специально чтобы увеличить наглядность. Так что ты исказил мою методику.
hulio; dgolovanov; METAL; borodatii; AzagTot; NittenRenegade; e-sin; EmpireSer; vasiliy_b; aspirin4eg; +10 Ответить 1
7. shrekerererer (StepanZaytsev) 26.09.12 02:24
я конечно не претендую на мнение авторитетное, но не проще ли все делать логическими схемами, еще с курса информтики так все делали, чем придумывать новые схемы?? это как на программировние
8. Владислав Мороз (vlad.frost) 26.09.12 12:49
(6) Вот представьте, инженер техподдержки, ему 35 лет. Он булеву алгебру учил двадцать лет назад в школе. У него ещё десять заявок в очереди и злой пользователь на линии. И вот он смотрит на ваш код и пытается понять, что же значит ваше семиэтажное выражение. Каковы шансы, что он легко поймёт, что вы имели ввиду, когда писали этот код?

Возможно, ваше выражение тождественно первоначальному, но легче читать его не стало.
9. Осипов Сергей (fixin) 26.09.12 13:13
(8) полностью согласен. Тормоз, ты нарушаешь принцип KISS.
10. Сергей Старых (tormozit) 26.09.12 13:52
(8), (9)
Это обычные споры для рефакторинга.
Выносить ли в отдельную функцию фрагмент кода, который с большой вероятностью будет вызван только в одном месте?
Оформлять ли в виде отдельной переменной выражение, которое с большой вероятностью будет использовано только в одном месте?
Выносить ли во временную таблицу пакета подзапрос, который с большой вероятностью будет использован только в одном месте?

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

Таким образом если есть возможность сохраняя приемлемую читаемость программы отказаться от лишних промежуточных переменных, то я рекомендую ее использовать. В случае сложных логических выражений этого помогает достичь предлагаемая методика.
CratosX; palsergeich; +2 1 Ответить 1
11. г. Казань Рустем Гумеров (Rustig) 26.09.12 22:29
ТормозАйти, у тебя наверняка есть еще какие-нибудь трюки, способы, личные методики программирования (разработки). Мне интересно и полезно читать как саму идею публикации, так и шлейф комментариев. :) так что просим на бис :)
METAL; kuzyara; Созинов; +3 Ответить
12. Тимофей Чернов (software1c) 26.09.12 23:27
Плюс автору. За методику ФОРМАТИРОВАНИЯ кода. Однозначно, четко и понятно даже пятикласснику
METAL; NittenRenegade; +2 Ответить
13. Александр Алёхин (new_user) 05.10.12 16:16
Че-т какие-то комментарии неоднозначные! Мне очень приемчик понравился, активно использую его в практике! Автору спасибо!..
RaketaSoft; +1 Ответить
14. Олег Пендраковский (aspirin4eg) 08.10.12 15:54
Применять булеву алгебру, на мой взгляд, следует именно для упрощения логических конструкций и исключения ненужных проверок в условиях. Иначе она несет только усложнение. Восприятие скобок облегчается если их записывать правильно. Тогда кстати и читаемость условий намного упрощается.
15. Андрей Калякин (kalyaka) 10.10.12 09:23
Форматирование однозначно повышает читаемость! Убрать бы еще лишние слова "Истина" и "Ложь" и будет вообще отлично.
16. Сергей Старых (tormozit) 10.10.12 09:34
(15) В таком случае ты не сможешь просто закомментировать первое условие в каждой группе и сохранить синтаксическую корректность.
Spec1c82; +1 Ответить
17. EfiopReal (Созинов) 10.10.12 17:13
За заметку +. Было бы неплохо почитать об улучшении читаемости кода, если есть еще методики, а то недавно свой код годовой давности правил - был в шоке. Да и сейчас зачастую пишу такое, что потом себе руки отрезать хочется :-)
amon_ra; Ворчун; +2 Ответить 1
18. Владислав Мороз (vlad.frost) 10.10.12 17:35
19. Александр Хомяк (logarifm) 11.10.12 12:24
Мозговынос и не нахожу в таких условиях ничего кроме трудностей их отладки и восприятия. Мое ИМХО - обойтись гораздо проще и более эфективно написав несколько упрощенных условий чем одно но с сумасшедшшей структурой. Не оправдано это... Остаюсь при своем мнении и не ставлю ни плюса ни минуса.

ЗЫ. охота было влипить минус но остановило лишь то, что автор знает о чем пишет и это труд. А минус за сложность и не рациональное использование таких выражений. (Игра слов)
корум; aspirin4eg; mrXoxot; const000; Yashazz; dj_serega; zikonza; ffgnebel; klinval; Sashko773; Manticor; Tedman; DrAku1a; Craig; OVladius; Evil Beaver; igor-pn; Eillecho; vlad.frost; +19 1 Ответить 1
20. Эстер Коган (e.kogan) 29.08.13 12:17
(19) logarifm, лично мне приятнее читать грамотный и структурированный текст, чем конструкции вроде "Мое ИМХО - обойтись гораздо проще и более эфективно написав несколько упрощенных условий чем одно но с сумасшедшшей структурой. Не оправдано это..."

//SARCAZM//
21. Александр Хомяк (logarifm) 29.08.13 12:38
(20) e.kogan, А в чем не граммотность опридиления условий в простом виде:

Если Тогда
Если Тогда
Если Тогда

и т.п.
КонецЕсли;

Причем здесь конструктивность языка вообще!? Тебе как минимум сюда или наподобие этого:
читать книги С.Макконнелла "Совершенный код". Вообще не путай статью автора из структурированным кодом!
22. Эстер Коган (e.kogan) 29.08.13 13:47
(21) logarifm, спасибо, Стива Макконнелла читала. Я про чистоту и системность мышления, выражающуюся не только в программном коде, но и в естественном языке. А с этим у вас определённо проблемы.
23. Александр Хомяк (logarifm) 29.08.13 13:55
на просторы интернета.... ахахах смешно. Облегчу с поиском:
И́МХО или ИМХО́ (от англ. IMHO, In My Humble Opinion), также имхо или imho (строчными буквами) — русская транслитерация английского акронима, означающего «по моему́ скромному мнению» .

Область использования сокращения — эхоконференции, форумы, чаты, и другие (как публичные, так и частные) места для выражения своего отношения к какому-нибудь предмету. В разговорной речи встречается относительно редко.
24. Андрей Акулов (DrAku1a) 21.11.13 04:03
(21)
Если ТипЗнч(Объект)=Тип("СправочникСсылка.Номенклатура") Тогда
Если НЕ Объект.Пустая() Тогда
...
КонецЕсли
КонецЕсли;
...Показать Скрыть
25. Yan Tsys (YanTsys) 21.11.13 13:18
(23) logarifm, думаю проблема не в "ИМХО", а в формулировке "обойтись гораздо проще и эфективно", для того чтобы понять какой смысл вы заложили в предложение попробуйте составить обратное. Как оно будет звучать: "обойтись сложнее и неэффективно"?
Кроме того:
"влИпить",
"статью автора ИЗ структурированным кодом",
"сумасшедшШей",
"опрИдИления".

Ну и на вопрос:
"А в чем не граммотность опридиления условий в простом виде:
Если Тогда
Если Тогда
Если Тогда
и т.п.
КонецЕсли;
"

1С при проверке на такой код выдаст ошибку:
err: Ожидается ключевое слово 'КонецЕсли'

Граммотно писать:
Если Тогда
ИначеЕсли Тогда
ИначеЕсли Тогда
и т.п.
КонецЕсли;

И если девушка читала Стива Макконнелла то с вашей стороны будет "наивно" полагать, что она не понимает значение вашего "ИМХО", и проверьте на приборах скромность вашего мнения, лично мне кажется вы его недооцениваете :)
26. Александр Хомяк (logarifm) 21.11.13 13:29
Ой, а я просто и не знал, что там ошибка, а еще ошибка в том что в условиях нет логических выражений и что?
27. Антон Бордачев (iTony73) 25.11.13 17:17
А как же ?(Условие, истина, Ложь), на наглядно?
Так же для простоты и наглядности можно использовать соответствие, то есть заводить несколько вариантов, а потом небольшим условием его обходить.
28. Игорь Чайкин (ЧИА) 04.02.14 13:35
не буду придираться к коду
придерусь к идее

как приверженец написания кода через отладчик, считаю, что
1. условия должны быть простыми
2. везде должно быть место точке останова

таким образом, надо писать не одну дикую проверку
и не структуру типа

Если Тогда
ИначеЕсли Тогда
ИначеЕсли Тогда
КонецЕсли;

а структуру типа

Если Тогда

Если Тогда
Иначе
КонецЕсли;

Иначе

Если Тогда
Иначе
КонецЕсли;

КонецЕсли;
29. Сергей Старых (tormozit) 04.02.14 13:48
(28) Чтобы было более наглядно, приведи свой вариант кода для примера из статьи.
30. Игорь Чайкин (ЧИА) 04.02.14 15:12
НадоСчитать = Ложь;

Если ГруппаРасчета = мИдГруппы7 Тогда

Если (НомерИзменяемойКолонки = "8") Тогда
    НадоСчитать = Истина;
Иначе
    //
КонецЕсли;

Иначе

Если 
    (НомерИзменяемойКолонки = "7") 
    Или 
    (НомерИзменяемойКолонки = "4")
    Или 
    (НомерИзменяемойКолонки = "5")
    Тогда
    НадоСчитать = Истина;
Иначе
    //
КонецЕсли;

КонецЕсли;

Если НадоСчитать  Тогда
    Расчет(ГруппаРасчета);
КонецЕсли;

...Показать Скрыть
31. Игорь Чайкин (ЧИА) 04.02.14 15:39
по тем же причинам

запросы рекомендую писать не через вложенные
а через временные таблицы

и отлаживать проще
и нагляднее

и быстрее обычно выполняется
32. Сергей Старых (tormozit) 04.02.14 16:19
(30) Сразу видно дублирование кода "Расчет(ГруппаРасчета);". Подумай что будет, если там не одна строка будет, а 30 например =)
33. Игорь Чайкин (ЧИА) 04.02.14 16:23
(32) tormozit,
что будет, если там не одна строка будет, а 30 например

если в блоке больше 8 строк (требования моих наставников), ну или 16 (один экран, мои), это или процедура, или функция

переделал с одним запуском
34. Разве это имеет значение (-fox-) 05.02.14 09:07
По мне, если условие сложное, его всегда можно разбить на более простые + сделать грамотные комментарии.
35. Елена Ситникова (lesenoklenok) 07.02.14 09:54
Спасибо за идею, но мне кажется что итоговый вариант как то смотрится сложнее. Ну это только лишь мое мнение.
36. poyson (poyson) 24.03.14 14:40
Чтоб понять надо вникнуть :). В целом интересный подход. Спасибо.
37. Александр Пряшников (Пан) 24.05.14 12:51
любая структуризация полезна, спасибо
38. Илья Вольных (xFoG) 09.07.14 10:43
(30) ЧИА,
таким образом, надо писать не одну дикую проверку
и не структуру типа

Если Тогда
ИначеЕсли Тогда
ИначеЕсли Тогда
КонецЕсли;

а структуру типа

Если Тогда

Если Тогда
Иначе
КонецЕсли;

В первом случае после получения истины мы остальные проверки не проводим, во втором - проверяем все, что увеличивает время выполнения участка кода.
(31) ЧИА,
запросы рекомендую писать не через вложенные
а через временные таблицы

и отлаживать проще
и нагляднее

Простота отладки сомнительна. Скопировать текст вложенного запроса в консоль проще.
(33) ЧИА
если в блоке больше 8 строк (требования моих наставников), ну или 16 (один экран, мои), это или процедура, или функция

Всегда считал, что единственным условием является множественность использования блока, а не размер. Каким же шрифтом вы пишите, что у вас 16 строк на экран умещается?
39. Андрей Ильин (su_mai) 13.12.14 09:50
(1) А я думал, что он это ты :), ошибся :)))
40. Андрей Ильин (su_mai) 13.12.14 09:53
(10) tormozit, Все неверно! Читай про процедурную декомпозицию кода: https://ru.wikipedia.org/wiki/%D0%94%D0%B5%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%B7%D0­%B8%D1%86%D0%B8%D1%8F.
41. You Name (YouName) 13.12.14 23:24
Мне этот метод понравился! Возьму на вооружение.
По мне любой метод найдёт своего "пользователя".
42. Павел Жихарев (palsergeich) 19.02.15 15:42
Это как стенография, овладевшим все понятно, но конкретно меня количество скобочек еще никогда не смущало, а вот такая запись нормально прочиталась с 5го раза и не факт что другое выражение я прочитаю с 1ой попытки.
Метод интересный, но увы, мне за такое оторвут пальцы.
Просто показал товарищу конечное выражение, он мне в ответ скинул картинку, как он это видит.

Таки код должен быстро читаться не только Вами но и другими. А стандартное написание подразумевает запись в исходном виде.
43. Данила Елистратов (CagoBHuK) 29.05.15 09:27
(21) logarifm, внутри каждого Если придется повторять один и тот же код.
44. Kiber_ Юрий (Kiber_) 02.06.15 17:19
По поводу группировки логических выражений в блоки на основе "одинаковых логических операций" - целиком согласен с автором.
Но как-то показался очень сложным процесс раскрытия скобок.
Также не понравились "Ложь" и "Истина" в качестве первого операнда блока.
Сам-бы написал так:
Если НомерИзменяемойКолонки = "4"
	Или НомерИзменяемойКолонки = "5"
	Или НомерИзменяемойКолонки = "7"
	Или (НомерИзменяемойКолонки = "8" И ГруппаРасчета = мИдГруппы7) Тогда
	Расчет(ГруппаРасчета);
КонецЕсли;
...Показать Скрыть
45. Сергей Старых (tormozit) 02.06.15 19:40
(44) Так плохо отличим конец условия от начала кода под условием.
46. Dyuha K (dyuha) 30.08.15 04:17
У этого метода два офигенных плюса:
Можно быстро закомментировать любое условие;
При отладке и точку останова можно поставить в любом месте, и шагать по F10/F11 удобней.
Spec1c82; +1 Ответить
47. spec spec (Spec1c82) 04.09.15 13:07
Сначала глянул только исходное условие и конечный результат. Сразу не понял зачем нужны "Если Ложь ИЛИ" и "Если Истина И". Пришлось прочитать полностью и после осмысления понял всю красоту предлагаемого решения.
Очень наглядно было сравнение с отбором настроек компоновки данных.
Удобно что легко можно закомментировать любое из условий, в том числе и первое. Соответственно отладка тоже упрощается.
Впрочем порой красоту структуры в целях оптимизации придется нарушить и в первую очередь проверять наиболее вероятные условия (если есть такое понимание или статистика).
dgolovanov; +1 Ответить
48. Виктор (vvirus) 18.09.15 07:45
Красивый подход ,
использую такой вариант записи

(+) при переходе на динамические условия "открытый" ИЛИ не блокирует дополнительные условия
(+) сохраняеться история введения ограничений
(-) читаеться возможно сложнее чем вариант топик стартера

Если (
(НомерИзменяемойКолонки = "4")
Или (НомерИзменяемойКолонки = "5")
)
Или (
(
(НомерИзменяемойКолонки = "7")
Или (НомерИзменяемойКолонки = "8")
И (ГруппаРасчета = мИдГруппы7)
)
)
Тогда
Расчет(ГруппаРасчета);
КонецЕсли;



но и это у меня не оптимизация, а лёгкое упрощение чтения

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

то есть ...


Если ( ТекИзменяемаяКолонка.Рассчет ИЛИ ТекГруппаРасчета.Рассчет )
Тогда Расчет(ТекГруппаРасчета);
КонецЕсли;

Разумеется группа условий содержащая ИЛИ всегда в скобках
49. Яков Коган (Yashazz) 01.10.15 14:00
Уникально редкий случай, когда я склонен согласиться с fixin'ом. Сложную логику надо не переписывать так, этак и разэдак, а упрощать. Реальным упрощением является грамотное использование промежуточных переменных, это и отлаживать легче.
50. Сергей Старых (tormozit) 01.10.15 14:21
(49) Ну это тот же холивар "алгоритмическое или декларативное", "пакет из 10 запросов или один сложный запрос". Я показал для тех, кто предпочитает декларативный стиль, как на мой взгляд оптимальнее оформлять такие выражения. Любители алгоритмического стиля могут конечно результат каждой логической операции помещать в отдельную переменную и давать ей семантически качественное имя =), но это тоже крайность. Так что хороший разработчик должен уметь грамотно сочетать эти подходы и не "холиварить".
hulio; NittenRenegade; dgolovanov; Гриффин; +4 Ответить
51. Владимир Попов (NittenRenegade) 30.10.15 16:08
В начале мне запись не понравилась, т.к. и исходную я прочитал совершенно без труда. В отличие от вариантов людей, предлагавших разбивать на какие-то вызываемые части.
Однако после комментария software1c вернулся к получившейся записи и понял её. Действительно, для сложных условий запись отличная.
52. Гость 16.11.15 15:15
Интересная статья + нашел для себя несколько интересных способов оформления в комментариях.
Вывод:
+ Не приветствуются собственные велосипеды (Если Ложь Или...)
+ Условие 1го уровня - 1 таб, 2го уровня 2 таб и т.д. для читабельности
+ Одно условие = одна строка, для возможности быстро закомментировать

Если
	НомерИзменяемойКолонки = "4" Или
	НомерИзменяемойКолонки = "5" Или
	НомерИзменяемойКолонки = "7" Или
	( НомерИзменяемойКолонки = "8" И ГруппаРасчета = мИдГруппы7 )
Тогда
	// ...
КонецЕсли;
...Показать Скрыть
53. Илья Вольных (xFoG) 18.11.15 11:02
(52) HardCoder,
Только "ИЛИ" в твоем примере хорошо бы писать перед тем выражением, к которому оно относится. Как и запятые и т.д.
Тогда, удалив или закомментив строку, ты не пролучишь ругань на лишнее "ИЛИ".
54. Решитко Дмитрий (grumagargler) 31.12.15 01:59
а почему просто не убрать лишние скобки?

	Если (НомерИзменяемойКолонки = "4"
		Или НомерИзменяемойКолонки = "5"
		Или НомерИзменяемойКолонки = "7")
		Или (НомерИзменяемойКолонки = "8"
			И ГруппаРасчета = мИдГруппы7) Тогда
		//...
	КонецЕсли;
...Показать Скрыть


плюс, если уж заботится о качестве кода, допускать трехсловные идентификаторы нельзя.
А если нужен идентификатор из трех слов, то значит сам контекст уже кандидат на рефактор и разбиение на более мелкие функции.
55. Матти Нюкянен (Nykyanen) 13.01.16 09:24
За часть про оформление (+) за часть про Рефакторинг (-).
Ведь даже школьник знает что выражения типа: А или Б или В = не (не А и не Б и не В)
Решать такой пример легче и человеку и машине, так как при использовании только И без ИЛИ и получении первой ложь все выражение в скобках будет ложь.
Особенно это важно в запросах. Так как ИЛИ в секции ГДЕ запроса при выполнении выполнит два запроса с каждым из условий и сделает их объединение.

Вывод идем учить преобразования логических выражений, кто ещё не в курсе что это такое.
56. Сергей Старых (tormozit) 13.01.16 09:52
(55) Nykyanen,
Ведь даже школьник знает что выражения типа: А или Б или В = не (не А и не Б и не В)

Судя по комментам здесь, это ошибочное утверждение. Не уверен, что мысль твою про рефакторинг я понял. Ты предлагаешь вообще не использовать оператор ИЛИ что ли? Если так то почему он есть во всех языках, раз он такой вредный и избыточный?
57. Матти Нюкянен (Nykyanen) 13.01.16 14:31
(56) Цель рефакторинга — сделать код программы легче для понимания. В основе рефакторинга лежит последовательность небольших эквивалентных (то есть сохраняющих поведение) преобразований.

Я хотел добавить, что выполнив логические преобразования выражений можно упростить понимание и так же часто получается повысить скорость работы. Согласен, что не всегда замена всех ИЛИ на И упростит запись и понимание, но на моей практике в 80% случаев замена ИЛИ на И упрощает понимание. Так же в процессе логические преобразования оказывается, что некоторые из выражений не влияют на результат всего выражения и/или можно сократить повторяющиеся выражения.

Конечно ИЛИ имеет право на жизнь как и много чего другого. Тут как с сортировкой можно в лоб сортировать, а можно пузырьком или еще каким то более хитрым методом.

Вот пример преобразования выражения из статьи.
((НомерИзменяемойКолонки = "4") Или (НомерИзменяемойКолонки = "5"))
Или (((НомерИзменяемойКолонки = "7") Или (НомерИзменяемойКолонки = "8")
И (ГруппаРасчета = мИдГруппы7))) | {замена на буквы по порядку на АБВГД} |
(А ИЛИ Б) ИЛИ (В ИЛИ (Г И Д)) =
А ИЛИ Б ИЛИ В ИЛИ (Г И Д) =
НЕ(НЕ А И НЕ Б И НЕ В И НЕ(Г И Д)) =
НЕ(НЕ(НомерИзменяемойКолонки = "4") И НЕ(НомерИзменяемойКолонки = "5") И НЕ(НомерИзменяемойКолонки = "7") И НЕ((НомерИзменяемойКолонки = "8") И (ГруппаРасчета = мИдГруппы7))) =
НЕ(НомерИзменяемойКолонки <> "4"
И НомерИзменяемойКолонки <> "5"
И НомерИзменяемойКолонки <> "7"
И НЕ((НомерИзменяемойКолонки = "8") И (ГруппаРасчета = мИдГруппы7)))

Так как в скобках все через И а за скобками НЕ, тогда если хотя бы одно выражение равно ЛОЖЬ в скобках, тогда и все выражение в скобках равно ЛОЖЬ, а все выражение равно ИСТИНА. Пример, НомерИзменяемойКолонки = 5, тогда все выражение в скобках равно ложь, а все выражение равно истина.
58. Сергей Есин (e-sin) 10.02.16 21:08
(54) grumagargler,
Лучше совсем убрать.

Если НомерИзменяемойКолонки = "4"
	Или НомерИзменяемойКолонки = "5"
	Или НомерИзменяемойКолонки = "7"
	Или НомерИзменяемойКолонки = "8" И ГруппаРасчета = мИдГруппы7 Тогда
		//...
КонецЕсли;
...Показать Скрыть
59. Максим Бурляев (maks_20) 01.03.16 11:03
Пользуюсь такой методикой. Солидарен с автором - удобно, наглядно, читабельно. Стоит один раз понять всю логику и потом уже проблем не будет.
60. Эльдар Гамзаев (lunjio) 28.08.16 23:17
книга "Совершенный код", совет автора - объединять такие условия в логически понятные группы, вместо НомерИзменяемойКолонки = "4" вынести предварительно в отдельную переменную и писать ПользовательМеняетКолонкуЦена = НомерИзменяемойКолонки = "4", а в условиях уже будет Если ПользовательМеняетКолонкуЦена ИЛИ ПользовательМеняетКолонкуСумма и т.д, сейчас такие процессоры, что нужно идти в сторону удобночитаемости кода, и не заморачиваться на том, что выполнится пару лишних условий в жертву удобночитаемости и логического смысла кода.
корум; +1 Ответить