Автор Тема: Борьба с вложенными IF  (Прочитано 3594 раз)

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Борьба с вложенными IF
« : Ноябрь 08, 2013, 05:47:28 pm »
PROCEDURE CloseWindow (w: Windows.Window);
        VAR res: INTEGER; msg: Sequencers.CloseMsg;
    BEGIN
        IF w # NIL THEN
            IF ~w.sub THEN
                msg.sticky := FALSE; w.seq.Notify(msg);
                IF ~msg.sticky THEN
                    IF w.seq.Dirty() & ~(Windows.neverDirty IN w.flags) THEN
                        HostDialog.CloseDialog(w, quit, res);
                        IF res = HostDialog.save THEN
                            SaveWindow(w, FALSE);    (* if saving is canceled, document remains dirty *)
                            IF w.seq.Dirty() THEN quit := FALSE
                            ELSE Windows.dir.Close(w)
                            END
                        ELSIF res = HostDialog.cancel THEN quit := FALSE
                        ELSE Windows.dir.Close(w)
                        END
                    ELSE Windows.dir.Close(w)
                    END
                ELSE quit := FALSE
                END
            ELSE Windows.dir.Close(w)
            END;
            IF ~quit THEN Kernel.Cleanup END
        END
    END CloseWindow;

Как это переписать чтобы повысилась читабельность?

Илья Ермаков

  • Sr. Member
  • ****
  • Сообщений: 493
    • Просмотр профиля
Re: Борьба с вложенными IF
« Ответ #1 : Ноябрь 09, 2013, 09:34:38 am »
На ДРАКОНе (шутка) :)

На самом деле, важная ситуация, я её всегда студентам объясняю - с разными способами решения.

Я практикую флаг ok:

ok := Cond1;
IF ok THEN
  ...
  ok := Cond2
END;
IF ok THEN
  ...
  ok := Cond3
END


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

Также разбираю со студентами альтернативные способы, чтобы, по крайней мере, не дублировать ELSE:

ok := FALSE;
IF Cond1 THEN
  ...
  IF CondN THEN
    ok := TRUE
  END
END

(когда присутствует в коде какое-то изменение состояния, влияющее на дальнейшее выполнение программы - например, здесь ok := FALSE и ok := TRUE, или смена состояния конечного автомата, я жирным выделяю это обычно)

Ну или классика, котрую сам не очень люблю, но студентам показываю: оформить каждый этап отдельной функцией (вложенной, видимо) и записать:
IF Stage1() & Stage2() & Stage3() ...

или ok := Stage1() & Stage2() & Stage3()

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Борьба с вложенными IF
« Ответ #2 : Ноябрь 09, 2013, 11:20:11 am »
Как это переписать чтобы повысилась читабельность?
1) Пересмотреть логику работы.
2) Использовать сверку кода в IDE

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Борьба с вложенными IF
« Ответ #3 : Ноябрь 09, 2013, 12:36:05 pm »
Как это переписать чтобы повысилась читабельность?

Уйти в монастырь.
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…