Erlang:简单重构

发布于 2024-09-02 09:14:38 字数 574 浏览 6 评论 0原文

考虑一下代码:

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。 有什么方法可以概括这种行为(重构此代码)?我的意思是,在所有命令中放置相同的大小写并不是一个好主意。

Consider the code:

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

Now imagine that there are a lot of commands and they are all call is_registered at first.
Is there any way to generalize this behavior (refactor this code)? I mean that it's not a good idea to place the same case in all the commands.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

情归归情 2024-09-09 09:14:38

我会和

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

I'd go with

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
终遇你 2024-09-09 09:14:38

我认为 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(),并通过第一个参数消除歧义。

I think ctulahoops' code reads better refactored like so:

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).

This takes advantage of the fact that functions are first-class entities in Erlang. You can pass them into functions, even define them anonymously inline in the call. Each function can be named differently. cthulahoops' method requires that all your command functions be predefined and called run_command(), disambiguated by their first argument.

贩梦商人 2024-09-09 09:14:38
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 可能是您的朋友。

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

Also Wrangler, an interactive refactoring tool, might be your friend.

帝王念 2024-09-09 09:14:38

我更喜欢使用异常。它将允许针对成功案例进行编程,并减少缩进级别的使用。

I like the use of exceptions better. It would allow programming for the successful case, and it decrease the use of indentation levels.

一身仙ぐ女味 2024-09-09 09:14:38

我更喜欢这种方式,它提供了更大的灵活性:

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}.

I prefer this way, it gives more flexibility:

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}.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文