Oberon space

General Category => Общий раздел => Тема начата: ilovb от Ноябрь 08, 2013, 05:47:28 pm

Название: Борьба с вложенными IF
Отправлено: ilovb от Ноябрь 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;

Как это переписать чтобы повысилась читабельность?
Название: Re: Борьба с вложенными IF
Отправлено: Илья Ермаков от Ноябрь 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()
Название: Re: Борьба с вложенными IF
Отправлено: Kemet от Ноябрь 09, 2013, 11:20:11 am
Как это переписать чтобы повысилась читабельность?
1) Пересмотреть логику работы.
2) Использовать сверку кода в IDE
Название: Re: Борьба с вложенными IF
Отправлено: Geniepro от Ноябрь 09, 2013, 12:36:05 pm
Как это переписать чтобы повысилась читабельность?

Уйти в монастырь.