Erlang: простой рефакторинг - PullRequest
5 голосов
/ 20 мая 2010

Рассмотрим код:

f(command1, UserId) ->
    case is_registered(UserId) of
        true ->
            %% do command1
            ok;
        false ->
            not_registered
    end;

f(command2, UserId) ->
    case is_registered(UserId) of
        true ->
            %% do command2
            ok;
        false ->
            not_registered
    end.

is_registered(UserId) ->
    %% some checks

Теперь представьте, что команд много, и все они сначала вызывают is_registered . Есть ли способ обобщить это поведение (рефакторинг этого кода)? Я имею в виду, что не стоит помещать один и тот же case во все команды.

Ответы [ 5 ]

8 голосов
/ 20 мая 2010

Я бы пошел с

f(Command, UserId) ->
    case is_registered(UserId) of
         true  ->
             run_command(Command);
         false ->
             not_registered
    end.


run_command(command1) -> ok;   % do command1
run_command(command2) -> ok.   % do command2
5 голосов
/ 21 мая 2010

Я думаю, что код ctulahoops читается лучше, рефакторинг выглядит так:

run_command(Command, UserId) ->
    case is_registered(UserId) of
         true  ->
             Command();
         false ->
             not_registered
    end.

run_command(some_function_you_define);
run_command(some_other_function_you_define);
run_command(fun() -> do_some_ad_hoc_thing_here end).

Это использует тот факт, что функции являются первоклассными сущностями в Erlang.Вы можете передать их в функции, даже определить их анонимно в строке при вызове.Каждую функцию можно назвать по-разному.Метод cthulahoops требует, чтобы все ваши командные функции были предопределены и вызваны run_command (), устраняющие неоднозначность по их первому аргументу.

2 голосов
/ 20 мая 2010
f(Command, UserId) ->
     Registered = is_registered(UserID),   
     case {Command, Registered} of
          {_, False} ->
               not_registered;
          {command1, True} ->
               %% do command1
               ok;
          {command2, True} ->
               %% do command2
               ok
     end.

is_registered(UserId) ->
     %% some checks

Также Wrangler , интерактивный инструмент рефакторинга, может быть вашим другом.

0 голосов
/ 08 января 2017

Я предпочитаю этот способ, он дает больше гибкости:

f(Command, UserId) ->
    f(Command,is_registered(UserId),UserID).

f(command1,true,_UserID) -> do_command1();
% if command2 does not need to be registered but uses UserID, for registration for example
f(command2,_Reg,UserID) -> do_command2(User_ID);
f(_,false,_UserID) -> {error, not_registered}.
0 голосов
/ 20 мая 2010

Мне больше нравится использование исключений. Это позволило бы программирование для успешного случая и уменьшило бы использование уровней отступов.

...