Skip to content

O Padrão Adapter

Álax de Carvalho Alves edited this page Dec 2, 2017 · 7 revisions

Diagrama de representação do padrão Adapter

Um adapter ou wrapper fornece uma interface para diferentes classes para trabalhar em conjunto. No padrão object adapter, o módulo contém uma instância da classe que ele "engloba". Nessa situação, o wrapper faz as chamadas para a instância do objeto "englobado".

Em resumo, o padrão de projetos Adapter consiste em adaptar a interface de uma classe ou objeto para ser usada de outra forma, porém sem alterar a interface ou implementação.

Um caso comum é quando desenvolvemos um código cliente que pretende usar diversas fontes heterogêneas.

O principal trunfo do padrão de projetos Adapter é permitir reuso do código de forma consistente, mantendo compatibilidade com outras bibliotecas e versões anteriores de código. Uma classe adaptadora nada mais é do que uma classe que implementa a interface que se deseja usar e delega a real execução para uma classe terceira que possui a implementação que desejamos usar.

GitHub Adapter

No Rails, o padrão adapter geralmente é implementado para "englobar" os clientes da API, fornecendo uma interface reutilizável para se comunicar com APIs externas. No nosso caso, usamos este padrão para refatorar o código que escrevemos que se comunica com a API do GitHub(OctoKit Client).

Percebemos que estávamos violando alguns princípios, como "Separation of concerns" e "Single responsibility", por isso houve um esforço de refatoração, o que ajudou a modularizar mais o código, e facilitou a construção dos testes.

Nosso código antes do Adapter

Podemos ver no código abaixo que em apenas em um único método eram feitas diversas chamadas ao cliente Octokit. Por exemplo, podemos ver que faz-se uma requisição para encontrar o usuário do GitHub, depois faz-se uma requisição para encontrar os repositórios daquele usuário, requisita-se posteriormente as organizações daquele usuário e em seguida os repositórios daquela organização(ões). Ou seja, logo de cara são feitas quatro coisas totalmente independentes dentro de um único método.

def github_projects_list
    @current_user = AuthorizeApiRequest.call(request.headers).result
    @client = Octokit::Client.new(access_token: @current_user.access_token)

    user_login = @client.user.login
    user_repos = []
    @repos = @client.repositories(user_login)
    @form_params = { user: [] }
    @form_params[:user].push(login: user_login)

    @repos.each do |repo|
      user_repos.push(repo.name)
    end
    @form_params[:user].push(repos: user_repos)

    @orgs = @client.organizations(user_login)
    @form_params2 = { orgs: [] }
    @orgs.each do |org|
      repos = @client.organization_repositories(org.login)
      repos_names = []
      repos.each do |repo|
        repos_names.push(repo.name)
      end
      @form_params2[:orgs].push(name: org.login, repos: repos_names)
    end

    @form_params3 = @form_params2.merge(@form_params)


    render json: @form_params3
end

Nosso código depois do Adapter

Após a refatoração, as chamadas às funções ficaram mais atômicas.

module Adapter
  class GitHubProject
    def initialize(request)
      @logged_user = AuthorizeApiRequest.call(request.headers).result
      @client = Octokit::Client.new(access_token: @logged_user.access_token)
    end

    def get_github_user
      user_login = @client.user.login
      return user_login
    end

    def get_github_repos(user_login)
      @client.repositories(user_login)
      end

    def get_github_orgs(user_login)
      @client.organizations(user_login)
    end

    def get_github_orgs_repos(org)
      @client.organization_repositories(org.login)
    end

    def get_contributors(github_slug)
      @client.contributors(github_slug)
    end
end

Vemos que a chamada às funções da Octokit ficaram modularizadas na controller.

def github_projects_list
    client = Adapter::GitHubProject.new(request)

    user_login = client.get_github_user

    @form_params_user = { user: [] }
    @form_params_user[:user].push(login: user_login)

    user_repos = []

    (client.get_github_repos(user_login)).each do |repo|
      user_repos.push(repo.name)
    end

    @form_params_user[:user].push(repos: user_repos)

    @form_params_orgs = { orgs: [] }

    (client.get_github_orgs(user_login)).each do |org|
      repos_names = []
      (client.get_github_orgs_repos(org)).each do |repo|
        repos_names.push(repo.name)
      end
      @form_params_orgs[:orgs].push(name: org.login, repos: repos_names)
    end

    @form_params_user_orgs = @form_params_orgs.merge(@form_params_user)

    render json: @form_params_user_orgs
end

Falko

Cronograma Versão 3


Acesso à aplicação


Equipe

Release 02

Sprint 1

Sprint 2

Sprint 3

Sprint 4

Sprint 5

Sprint 6

Sprint 7

Sprint 8

Sprint 9

Release 01

Gerenciamento do Projeto

Artefatos de Desenvolvimento

Encerramento

Clone this wiki locally