Elixir 中如何避免嵌套 if 语句?

kgp*_*per 2 elixir

有没有办法在 Elixir 中重构它以使其更具可读性?

  def validate(params) do
    Repo.start_link

    if validate_oauth_params(params) === true do
      oauth_client = Repo.get_by(OauthClient, random_id: params["client_id"], secret: params["secret"])

      if oauth_client != nil do
        allowed_grant_types = Poison.Parser.parse!(oauth_client.allowed_grant_types)
        if Map.has_key?(allowed_grant_types, params["grant_type"]) do
          case params["grant_type"] do
            "password" ->
              process_password_grant(params, oauth_client)
            "refresh_token" ->
              process_refresh_token_grant(params["refresh_token"], oauth_client)
            "client_credentials" ->
              process_client_credentials_grant(oauth_client)
            nil ->
              %{message: "Invalid oauth credentials", code: 400}
          end
        end
      else
        %{message: "Invalid oauth credentials", code: 400}
      end
    else
      %{message: "Invalid oauth credentials", code: 400}
    end
  end
Run Code Online (Sandbox Code Playgroud)

Elixir 的做法是什么,因为这段代码看起来像 PHP。不是我写的。

web*_*deb 5

你是对的,它看起来像 PHP。没有使用类似于模式匹配的长生不老药的好处。

重构这一块很困难,因为似乎其他方法也应该重构,以做得更干净。例如,validate_oauth_params函数“可以”返回一个元组而不是布尔值,因此您可以对其进行模式匹配,并且您将完成如下操作:

def validate(params) do
  case validate_oauth_params(params) do
    {:ok, params} -> choose_oauth_method params
    {:error} -> handle_error "Invalid params"
  end
end

defp choose_oauth_method(%{"grant_type" => "password"} = params) do
  process_password_grant(params)
end
defp choose_oauth_method(%{"grant_type" => nil}) do
  handle_error "Method undefined"
end

defp handle_error(msg), do: %{message: msg, code: 400}
defp handle_error(msg, code), do: %{message: msg, code: code}
defp handle_error(), do: %{message: "Default error massage", code: 400}
Run Code Online (Sandbox Code Playgroud)

像这样的东西,这根本不是工作代码,只是为了提供一个想法,模式匹配如何工作及其好处