编写易于测试,可扩展和可维护的代码

时间:2017-01-10 14:42:29

标签: elixir

我希望使用协议,编写一个易于测试,可扩展和可维护的代码

协议定义和实现如下:

defmodule SapOdataService.Auth do
  alias SapOdataService.Auth.UserLogin
  alias SapOdataService.Auth.UserInfo

  defprotocol Auth do
    @moduledoc """
     Protocol for SAP authentication.
    """
    def sign_in(data)
  end

  defimpl Auth, for: UserLogin do
    def sign_in(user) do
      %UserInfo{firstname: "Foo", lastname: "Boo", basic_auth: "Basic FooBoo"}
    end
  end
end

用户登录struct(user_login.ex):

defmodule SapOdataService.Auth.UserLogin do

  defstruct username: nil, password: nil
  @type t :: %__MODULE__{username: String.t, password: String.t}

end

用户信息结构(user_info.ex):

defmodule SapOdataService.Auth.UserInfo do

  defstruct firstname: nil, lastname: nil, basic_auth: nil
  @type t :: %__MODULE__{firstname: String.t, lastname: String.t, basic_auth: String.t}

end

正如您可以看到上面的代码,userlogin

的实现
defimpl Auth, for: UserLogin do
    def sign_in(user) do
      %UserInfo{firstname: "Foo", lastname: "Boo", basic_auth: "Basic FooBoo"}
    end
  end

如果给定的授权是否正确,sign_in函数将向服务器发出http post请求。

对于请求,我使用HTTPoison库向服务器发出请求。

假设,在一天HTTPoison将不再存在,一些开发人员开发新的HTTP客户端,然后我必须通过新的HTTP客户端替换HTTPoison

我的目标是编写易于扩展和维护的代码。

我从José那里读到了关于模拟的精彩article,他建议使用协议并将依赖项作为参数传递给函数。这就是问题,为什么我使用协议而不是行为。

此外,如何强制协议定义返回特定类型。就我而言,我想这样做:

defprotocol Auth do
  @moduledoc """
   Protocol for SAP authentication.
  """
  @spec sign_in(data) :: UserInfo.t
  def sign_in(data)
end

0 个答案:

没有答案