PHP

Removendo a lógica das views com presenters no Laravel

Um dos problemas mais clássicos de aplicações que utilizam MVC é a camada de view concentrar lógica ao invés de apenas aspectos relacionados à exibição. Veremos nesse artigo como isso pode ser contornado.

há 6 anos 1 mês

Formação Desenvolvedor PHP
Conheça a formação em detalhes

Um dos problemas mais clássicos de aplicações que utilizam MVC é a camada de view concentrar lógica ao invés de apenas aspectos relacionados à exibição. Veremos nesse artigo como isso pode ser contornado.

Frameworks como Laravel e Symfony utilizam por padrão template engines como Blade e Twig, respectivamente. Esses template engines possuem o intuito de diminuir a complexidade das views, no entanto, nem mesmo com essa ajuda as views ficam limpas o suficiente. Existem certos tratamentos que acabam sobrecarregando as views e também não é papel do model tratar isso. É nesse ponto que entram os Presenters.

Com intuito de ajudar na solução desses problemas podemos usar essa camada extra nas nossas aplicações. O principal objetivo dela é facilitar e devolver a informação já tratada para a view, diminuindo assim a quantidade de decisões que precisamos tomar dentro de nossas views e eximindo também os models de uma responsabilidade que não é deles.

Silex - Framework PHP
Curso Silex - Framework PHP
Conhecer o curso

Escolhendo e instalando um Presenter

Por padrão o Laravel não possui uma camada de Presenter, precisamos instalar via Package. Existem diversos packages que fazem esse processo, alguns mais elaborados e outros mais simples. No caso do nosso exemplo vamos usar o desenvolvido por Jeffrey Way que podemos fazer o download no packagist.org.

Basta executar o comando para o composer adicionar a dependência:

composer require laracasts/presenter

Criando e ligando o Presenter ao Model

A ideia é que cada método trate uma única informação, para mantermos também a classe de presenter organizada. No escopo do presenter é possível acessar as propriedades do model, assim fica mais fácil tratar as informações:

<?php
namespace AppPresenters;

use LaracastsPresenterPresenter;

class ProjectPresenter extends Presenter
{
    public function projectName()
    {
        return $this->id . ' ' . $this->name;
    }

    public function finalDate()
    {
        return $this->final_date->diffForHumans();
    }
}

Estamos criando um método que retorna o nome do projeto com o id e outro que retorna a data final do projeto em um formato mais fácil de ler.

Precisamos indicar o nome do presenter e usar uma trait que possui os métodos do pacote no model. Vamos supor que temos um model chamado Project, ele ficaria assim:

<?php

use AppPresentersProjectPresenter;
use LaracastsPresenterPresentableTrait;
use IlluminateDatabaseEloquentModel;

class Project extends Model
{
    use PresentableTrait;

    protected $presenter = ProjectPresenter::class;
}

Finalmente, agora podemos usar os métodos na view. Basta chamar em uma instancia do model um método chamado present(). Veja o exemplo:

{{ $project->present()->projectName }}

Estamos chamando o método ProjectName do presenter. Assim ele vai imprimir no formato ID Nome do projeto que retornamos no presenter.

Exemplo prático

Vamos imaginar que no model de projetos temos uma propriedade chamada status. Dependendo do status temos que definir a cor do label exibido para o usuário:

  • Status não iniciado: Etiqueta Azul
  • Status no prazo: Etiqueta Verde
  • Status atrasado: Etiqueta Vermelha

Usando as classes do bootstrap poderíamos fazer assim:

<span class="label label-{{ $project->present()->statusLabelColor }}">
	Status aqui
</span>

E no presenter definir a lógica:

<?php
namespace AppPresenters;

use LaracastsPresenterPresenter;

class ProjectPresenter extends Presenter
{
    public function statusLabelColor()
    {
            $labels = [
                'nao-iniciado' 	=> 'primary',
                'no-prazo'		=> 'success',
                'atrasado'		=> 'danger'
            ];

            return $labels[$this->status];
    }
}

Isoladamente não parece fazer tanta diferença utilizar os presenters ou não, porém, ao compararmos as views dos projetos que utilizam com os que não utilizam, isso fica muito claro.

O resultado é ainda melhor se o nome dos métodos do presenter forem definidos semanticamente, assim além de remover o código “feio” da view ainda a torna mais fácil de ser lida por humanos.

Está estudando sobre Eloquent? Veja como aliviar seus controllers com os eventos do Eloquent no Laravel e como usar escopos do Eloquent para construir consultas mais limpas no Laravel, tudo aqui no blog da Treina Web.

Já leu nossos artigos sobre Eloquent? Veja como aliviar seus controllers com os eventos do Eloquent no Laravel e como usar escopos do Eloquent para construir consultas mais limpas no Laravel, tudo aqui no blog da Treina Web.

Autor(a) do artigo

Elton Fonseca
Elton Fonseca

Professor e desenvolvedor. Formado em análise e desenvolvimento de sistema, pós graduado em engenharia e arquitetura de software. É autor de cursos em diversos temas, como, desenvolvimento back-end, cloud computing e CMSs. Nas horas vagas adora estudar sobre o mercado financeiro, cozinhar e brincar com pequeno Daniel. @eltonfonsecadev

Todos os artigos

Artigos relacionados Ver todos