2010-05-20 101 views
5

考慮代碼:二郎:簡單的重構

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在第一。 有什麼辦法來推廣這種行爲(重構此代碼)?我的意思是,在所有命令中放置相同的案例並不是一個好主意。

回答

7

我會去與

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 
2
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可能是你的朋友。

1

我喜歡使用例外更好的。它將允許爲成功案例編程,並減少縮進級別的使用。

5

我覺得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). 

這需要一個事實,即功能二郎一流的實體優勢。您可以將它們傳遞給函數,甚至可以在調用中匿名定義它們。每個功能都可以命名不同。 cthulahoops'方法要求你的所有命令函數都是預定義的,並且調用run_command(),通過它們的第一個參數進行消歧。

1

我喜歡這種方式,讓更多的靈活性:

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