Рассмотрите код:
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 сначала. Там какой-либо путь состоит в том, чтобы сделать вывод, это поведение (осуществите рефакторинг этот код)? Я подразумеваю, что это не хорошая идея поместить тот же случай во все команды.
Я бы выбрал
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
Мне больше нравится использование исключений. Это позволит программировать для успешного случая, и уменьшит использование уровней отступов.
Я думаю, что код 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 (), что устраняет неоднозначность их первого аргумента.
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 .