2010-05-20 11 views
5

Considere el código:Erlang: refactorización sencilla

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 

Ahora imagina que hay una gran cantidad de comandos y todos ellos son llamadas is_registered al principio. ¿Hay alguna manera de generalizar este comportamiento (refactorizar este código)? Quiero decir que no es una buena idea colocar la misma caja en todos los comandos.

Respuesta

7

me gustaría ir con

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 

también Wrangler, una herramienta interactiva refactorización, podría ser su amigo.

1

me gusta el uso de excepciones mejores. Permitiría la programación para el caso exitoso y disminuiría el uso de niveles de sangría.

5

creo código ctulahoops' lee mejor refactorizado así:

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

Esto se aprovecha del hecho de que las funciones son entidades de primera clase en Erlang. Puede pasarlos a funciones, incluso definirlos anónimamente en línea en la llamada. Cada función se puede nombrar de manera diferente. El método de cthulahoops requiere que todas sus funciones de comando estén predefinidas y se llamen run_command(), desambiguadas por su primer argumento.

1

Yo prefiero esta manera, se da una mayor flexibilidad:

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