Могу ли я установить состояние внутри функции? - PullRequest
3 голосов
/ 26 января 2011

У меня есть этот код:

procedure EstablishCommunication;
var
    State         : TStates;
    Attempts      : Byte;      
    procedure IncAttempts;
    begin
        Inc(Attempts);
    end;
begin
    State    := stReadDeviceID;
    Attempts := 0;

    while True do
    begin
        if Attempts >= MAX_ATTEMPTS then
        begin
            State := stError;
        end;
        case State of
            stReadDeviceID:
            begin
                // some code
                IncAttempts;
            end;
            stError:
            begin
                // Error code
            end;
        ...
        ...
        ...

Я хотел бы поместить код, который устанавливает состояние в stError, в рамках процедуры IncAttempts, в результате:

procedure EstablishCommunication;
var
    State         : TStates;
    Attempts      : Byte;      
    procedure IncAttempts;
    begin
        Inc(Attempts);

        if Attempts >= MAX_ATTEMPTS then
        begin
            State := stError;
        end;
    end;
begin
    State    := stReadDeviceID;
    Attempts := 0;

    while True do
    begin            
        case State of
            stReadDeviceID:
            begin
                // some code
                IncAttempts;
            end;
            stError:
            begin
                // Error code
            end;
        ...
        ...
        ...

ИтакЯ перенесу код в IncAttempts?

Это запах кода?

Если да, можете ли вы посоветовать мне лучший способ?

Ответы [ 3 ]

4 голосов
/ 26 января 2011

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

  • Будет ли когда-либо изменяться внутренняя функция, как в классе-потомке?
  • Можно ли переопределить внешний метод без вызова внутреннего метода и быть в порядке?
  • Имеет ли внутренняя функция практическое применение вне внешнего метода?
  • Достаточно ли сложна внутренняя функция, чтобы ее можно было подвергнуть модульному тестированию вне области применения внешнего метода?

Если применимо любое из вышеперечисленного, не используйте внутренний метод.

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

2 голосов
/ 26 января 2011

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

0 голосов
/ 27 января 2011

Я бы сказал, что у нового кода есть какой-то запах ...

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

В двух фрагментах кода, которые вы показываете, есть небольшая разница:

В первом исходном коде текущее состояние сохраняется в течение итерации, а новое состояние ошибки устанавливается в начало итерации, и оно всегда проверено.

Во втором рефакторированном коде состояние изменяется в середине итерации и изменяется только в том случае, еслисостояние stReadDeviceID.

Теперь, если последняя строка в этой итерации while True do равна if State = stError then Break;, тогда ваш первый код выполнит итерацию еще раз, изменив состояние на stErrorв начале, если итерация.Ваш второй код завершится в конце текущей итерации, и код в stError -разведении case -отверждения никогда не будет выполнен ...

Если вы хотите пройти всеи изучите шаблон проектирования состояния GoF, а затем посмотрите на следующие страницы:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...