zHz00 Untitled

вторник, 17 декабря 2024
01:51 Длинные условия
Сколько раз такое было, пишем оператор условия, а там:

if(flag1==True&&flag2==False&&function_call(a,b,c,d)>0)

и что-нибудь ещё.

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

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

2. Но я хотел написать про минорное упрощение. Нужно записывать условия в столбик. Я давно так делаю. Но недавно я обнаружил, что записывать в столбик можно по-разному. Можно написать:

if(flag1==True&&
flag2==False&&
function_call(a,b,c,d)>0)

А можно написать:

if(flag1==True
&&flag2==False
&&function_call(a,b,c,d)>0)

Я всегда использовал первый вариант, но убедился, что он неудобен. Логическая операция находится в конце строки, её надо постоянно искать глазами. А концы у каждой строки находятся в разном месте. Если расположить оператор в начале, то, во-первых, будет понятнее, что происходит, а во-вторых, можно для удобства дублировать оператор и в конце предыдущей строке, но уже в комментарии, типа //&& .

Но насчёт дублирования я пока не уверен, т.к. никогда так не делал.

3. Есть ещё один метод, назначить каждому условию в выражении отдельную логическую переменную.

bool b1=(flag1==True);
bool b2=(flag2==False);
bool b3=(function_call(a,b,c,d)>0);//скобки необязательны, но пусть будут на всякий случай
if(b1&&b2&&b3)

Какие есть особенности у этого метода?
Во-первых, если удастся дать условиям краткие понятные имена, а не b1, b2, b3, то это действительно упростит читаемость. Если имена будут условными, то упрощение тоже будет условным.
Во-вторых, упрощается отладка, поскольку вы получаете непосредственный доступ к частям логического выражения, а обычно такого доступа нет, т.к. условие выполняется в отладчике как одна строка.

@темы: Программирование, Говнокод

URL
Сегодня смотрел на машины и думал о женщинах...Или наобор...
Вспомнила сегодня голос и фразу Альбины, когда ей предлаг...
У меня были галюны. Правда. Слуховые.. хотя не зна, может...
Рождение ребенка займет девять месяцев, независимо от тог...
На земле весь род людской Чтит один кумир священный, ...
Где те милые времена, когда на Халяве.Ру у меня была стра...

17.12.2024 в 02:24

17.12.2024 в 02:24
Можно в конце строки табулировать все логические операторы, чтобы они выровнялись по вертикали.
URL

17.12.2024 в 02:27

17.12.2024 в 02:27
А сложные условия можно приводить к простым. Типа,
bool contition1 = function1(a,b,c);
bool condition2 =function2(x,y, z);

if (condition1 && condition2)
{ ... }

Или ты это и называешь конечным автоматом?
URL

17.12.2024 в 06:19

17.12.2024 в 06:19
Foul thing, ха, про выравнивание не думал. Будет сиротливо висеть &&?

Про condition1 и condition2. Я так иногда делаю. Про это я написать почему-то забыл, но теперь допишу. Тут есть джва варианта. Если удалось дать условиям понятные короткие названия, то это действительно приводит к упрощению понимания. Если же используются cond1, cond2 то это по большей части укорачивает только запись. Чтобы понять, надо всё равно изучить все строчки.

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

17.12.2024 в 06:57

17.12.2024 в 06:57
Если же используются cond1, cond2 то это по большей части укорачивает только запись
Часто встречается такое, что условий, допустим, штук шесть или семь, а то и больше. И в них входят переменные, сравнения, вызовы функций с длиными именами и параметрами. Все это группами соединяется через AND или OR, которые обрастают скобками, и в итоге получается такой франкенштейн, в котором уже непонятно, что вообще происходит, и кто кого по каким параметрам сравнивает и вызывает.
Я такие штуки не люблю и стараюсь превращать в разбиения по условиям, как я выше написал (пусть даже не с особо понятными названиями, но уж всяко лучше, чем месиво). Ну или можно превратить во вложенные ifы. Которые будет занимать больше места, но зато будут гораздо проще читаться и отлаживаться.
Кстати, с отладкой это очень помогает, потому что обычно условие if ( A && B || (C && D)) в отладчике проскакивает за один шаг, и фиг там разберешь, кто их них сработал или не сработал.
URL

17.12.2024 в 07:10

17.12.2024 в 07:10
Foul thing, уф, значит не у одного меня такая проблема.

ДА, для отладки условий такое помогает. Про это тоже допишу, спасибо.
URL

03.01.2025 в 01:51

03.01.2025 в 01:51
if (!flag1) return False
if (flag2) return False
return function_call(a, b, c, d) > 0;

Если же там воронежский вермишелеукладочный завод, то да, cond1, cond2:

if (cond1 && cond2 && (cond3 || cond4)) ...
if (cond1 && !cond2 && (cond3 || cond5)) ...
if (cond6 && !(cond1 || cond2) && cond4) ...
URL
Добавить комментарий

Расширенная форма

Подписаться на новые комментарии
Получать уведомления о новых комментариях на E-mail