엘릭서의 행동
Protocols
, Behaviours
também são uma forma de manter um padrão de interface/herança e até mesmo polimorfismo no Elixir.Vale lembrar que Elixir é uma linguagem de programação funcional, portanto, não é o nosso forte o conceito de objeto, classe e métodos. No final, semper estaremos falando sobre modulos e funções!
Então de que me serve possuir uma abstração para criar interface em uma tecnologia como esta?
세나리오
Imaginem que vamos desenvolver uma aplicação onde a pessoa insere seus dados para Consultar todos seus cartões de crédito, verificar se as faturas estão em dia, e inclusive gerar possíveis estratégias financeiras, etc...
Para isso precisamos criar uma API REST que irá Consultar de diversas fontes de cartões para validar os dados e processar as respostas finais.
Você consegue identificar um padrão nisso? Se precisamos Consultar mais de uma API externa para reunir os dados para a resposta final, isso significa que nosso código terá muitos módulos que serão 통신원 a proofores diferentes(예: Itaú, Nubank 등...)
문제a
Como iremos mapear todos esses módulos de proofores que vamos criar dentro do nosso sistema então? 정확한 집행을 보장하려면 어떤 절차를 거쳐야 합니까?
APIs externas podem ser distintas, possuir dados diferentes e respostas diferentes, isso pode se tornar um problema e pode nos levar a criar códigos aleatórios para solucionar cada tipo de API de uma forma desnecessária로 API를 외부에서 볼 수 있습니다.
행동
Com behaviors conseguimos criar um padrão comportamental, definindo uma assinatura pré-exigida pelo modulo, garantindo que todos os modulos lateres que irão se especializar naquela API precisarão implementar aqueles requisitos.
다른 방법으로는 API 외부 액세스에 대한 인터페이스가 없다고 생각하십시오.
defmodule Bank.API do
@moduledoc """
Este módulo é responsável por definir uma interface
padrão para os demais módulos de acesso ao
Banco implementarem.
"""
@type params() :: map()
@type response() :: {:ok, map()} | {:error, String.t()}
@doc """
Este método irá acessar a base externa e
retornar os dados bancários da pessoa usuária
"""
@callback call(params()) :: response()
end
os moduledocs e typespecs do nosso modulo, nos resta essa@callback
, que é exatamente o comando utilizado para definir as funções que deverão ser implementadas pelo modulo que claime se especializar nessa API.
Perceba o quão genérico nossa interface ficou, ela só da a entender que é uma API de Banco, com uma função de chamada. 순간적인 알고리즘은 방코의 품질을 평가하는 데 있어 모든 유형의 서비스를 제공해야 합니다(통해: API, gRPC, SOAP 등...). 에사 인터페이스를 구현하기 위한 모든 응답이 필요합니다.
Agora com nosso behavior bem definido, podemos seguir para a implementação do primeiro Client que iremos utilizar em nossa aplicação para Consultar os dados:
defmodule Bank.Nubank do
@moduledoc """
Módulo que implementa a requisição para a API do Nubank.
"""
@behaviour Bank.API
@impl true
def call(%{user_id: id}) do
id
|> nubank_url()
|> HTTPoison.get()
|> case do
{:ok, %{status_code: 200, body: response}} ->
{:ok, response}
{:error, reason} ->
{:error, reason}
end
end
defp nubank_url(id), do:
Application.get_env(:my_app, :nubank)[:url] <> "/user/#{id}"
end
(a requisição acima é meramente ilustrativa 😅)
O comando @behaviour Bank.API
descreve que nosso modulo Nubank
irá se especializar no Bank.API
, logo, ele deverá implementar a seguinte função: call/1
.
Com isto, temos nosso primeiro proofor implementado, yaay 🚀!
결론
Gosto de dizer que estamos definindo padrões comportamentais, com isso, quando vemos que um módulo específico implementa um Behaviour, já dá para ter uma ideia de quais funções ele roda, qual o seu propósito, como ele deve ser implementado em termos de input e output .
Esse tipo de padronização a juda a escalar nosso código, diminuir a curva de aprendizagem para novas pessoas desenvolvedoras e inclusive é uma ótima ferramenta para auto-documentar nosso código, deixa tudo mais descritivo e explícito!
당신의 행동이 무엇입니까? Gostaria decomplementar, adicionar ou remover alguma informações deste topico?
Reference
이 문제에 관하여(엘릭서의 행동), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/wlsf/behaviours-em-elixir-25i3
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Como iremos mapear todos esses módulos de proofores que vamos criar dentro do nosso sistema então? 정확한 집행을 보장하려면 어떤 절차를 거쳐야 합니까?
APIs externas podem ser distintas, possuir dados diferentes e respostas diferentes, isso pode se tornar um problema e pode nos levar a criar códigos aleatórios para solucionar cada tipo de API de uma forma desnecessária로 API를 외부에서 볼 수 있습니다.
행동
Com behaviors conseguimos criar um padrão comportamental, definindo uma assinatura pré-exigida pelo modulo, garantindo que todos os modulos lateres que irão se especializar naquela API precisarão implementar aqueles requisitos.
다른 방법으로는 API 외부 액세스에 대한 인터페이스가 없다고 생각하십시오.
defmodule Bank.API do
@moduledoc """
Este módulo é responsável por definir uma interface
padrão para os demais módulos de acesso ao
Banco implementarem.
"""
@type params() :: map()
@type response() :: {:ok, map()} | {:error, String.t()}
@doc """
Este método irá acessar a base externa e
retornar os dados bancários da pessoa usuária
"""
@callback call(params()) :: response()
end
os moduledocs e typespecs do nosso modulo, nos resta essa@callback
, que é exatamente o comando utilizado para definir as funções que deverão ser implementadas pelo modulo que claime se especializar nessa API.
Perceba o quão genérico nossa interface ficou, ela só da a entender que é uma API de Banco, com uma função de chamada. 순간적인 알고리즘은 방코의 품질을 평가하는 데 있어 모든 유형의 서비스를 제공해야 합니다(통해: API, gRPC, SOAP 등...). 에사 인터페이스를 구현하기 위한 모든 응답이 필요합니다.
Agora com nosso behavior bem definido, podemos seguir para a implementação do primeiro Client que iremos utilizar em nossa aplicação para Consultar os dados:
defmodule Bank.Nubank do
@moduledoc """
Módulo que implementa a requisição para a API do Nubank.
"""
@behaviour Bank.API
@impl true
def call(%{user_id: id}) do
id
|> nubank_url()
|> HTTPoison.get()
|> case do
{:ok, %{status_code: 200, body: response}} ->
{:ok, response}
{:error, reason} ->
{:error, reason}
end
end
defp nubank_url(id), do:
Application.get_env(:my_app, :nubank)[:url] <> "/user/#{id}"
end
(a requisição acima é meramente ilustrativa 😅)
O comando @behaviour Bank.API
descreve que nosso modulo Nubank
irá se especializar no Bank.API
, logo, ele deverá implementar a seguinte função: call/1
.
Com isto, temos nosso primeiro proofor implementado, yaay 🚀!
결론
Gosto de dizer que estamos definindo padrões comportamentais, com isso, quando vemos que um módulo específico implementa um Behaviour, já dá para ter uma ideia de quais funções ele roda, qual o seu propósito, como ele deve ser implementado em termos de input e output .
Esse tipo de padronização a juda a escalar nosso código, diminuir a curva de aprendizagem para novas pessoas desenvolvedoras e inclusive é uma ótima ferramenta para auto-documentar nosso código, deixa tudo mais descritivo e explícito!
당신의 행동이 무엇입니까? Gostaria decomplementar, adicionar ou remover alguma informações deste topico?
Reference
이 문제에 관하여(엘릭서의 행동), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/wlsf/behaviours-em-elixir-25i3
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
defmodule Bank.API do
@moduledoc """
Este módulo é responsável por definir uma interface
padrão para os demais módulos de acesso ao
Banco implementarem.
"""
@type params() :: map()
@type response() :: {:ok, map()} | {:error, String.t()}
@doc """
Este método irá acessar a base externa e
retornar os dados bancários da pessoa usuária
"""
@callback call(params()) :: response()
end
defmodule Bank.Nubank do
@moduledoc """
Módulo que implementa a requisição para a API do Nubank.
"""
@behaviour Bank.API
@impl true
def call(%{user_id: id}) do
id
|> nubank_url()
|> HTTPoison.get()
|> case do
{:ok, %{status_code: 200, body: response}} ->
{:ok, response}
{:error, reason} ->
{:error, reason}
end
end
defp nubank_url(id), do:
Application.get_env(:my_app, :nubank)[:url] <> "/user/#{id}"
end
Gosto de dizer que estamos definindo padrões comportamentais, com isso, quando vemos que um módulo específico implementa um Behaviour, já dá para ter uma ideia de quais funções ele roda, qual o seu propósito, como ele deve ser implementado em termos de input e output .
Esse tipo de padronização a juda a escalar nosso código, diminuir a curva de aprendizagem para novas pessoas desenvolvedoras e inclusive é uma ótima ferramenta para auto-documentar nosso código, deixa tudo mais descritivo e explícito!
당신의 행동이 무엇입니까? Gostaria decomplementar, adicionar ou remover alguma informações deste topico?
Reference
이 문제에 관하여(엘릭서의 행동), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/wlsf/behaviours-em-elixir-25i3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)