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.

Elton Fonseca 7 de março de 2018

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.

Doctrine ORM - Fundamentos
Curso de Doctrine ORM - Fundamentos
CONHEÇA 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.

Desenvolvedor Laravel Full-Stack
Formação: Desenvolvedor Laravel Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Laravel com maestria. Ao final desta formação, você terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso utilizando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

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.

Deixe seu comentário

Conheça o autor desse artigo

  • Foto Autor Elton Fonseca
    Elton Fonseca

    Professor e desenvolvedor. Formado em análise e desenvolvimento de sistema, pós graduando 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

    Posts desse Autor

Artigos relacionados