Fale com a gente no WhatsApp Fale com a gente no WhatsApp
Fale com a gente no WhatsApp

Desenvolvimento Back-end

Camadas e componentes do padrão arquitetural Porto

Conheça as camadas e componentes do padrão arquitetural Porto. Nesse artigo vamos aprender como cada camada se comunica e a responsabilidade dos componentes.

há 4 anos 1 mês


Você sabia que a TreinaWeb é a mais completa escola para desenvolvedores do mercado?

O que você encontrará aqui na TreinaWeb?

Conheça os nossos cursos

O padrão arquitetural Porto possui algumas camadas para tratar cada parte da aplicação. Nesse post vamos conhecer um pouco mais sobre cada uma dessas camadas e também sobre os componentes que podem compor a camada de containers.

Caso ainda não conheça o padrão arquitetural Porto, vale a leitura do artigo onde explicamos: O que é o padrão Porto e como ele funciona.

PHP - Orientação a Objetos - Parte 1
Curso PHP - Orientação a Objetos - Parte 1
Conhecer o curso

Camadas do padrão Porto

O padrão arquitetural Porto é composto por 2 camadas principais Ship (navio) e Containers. Conforme ilustra o diagrama abaixo:

diagrama que mostra as 3 camadas do padrão arquitetural porto

Existe também uma terceira camada mais conceitual chamada Sea (oceano), que podemos considerar como sendo os recursos de baixo nível que usamos na aplicação, como frameworks e bibliotecas, conforme mostrado acima.

Camada Ship

A camada Ship (navio) é a camada intermediária da nossa aplicação. Ela faz a ligação entre o código de baixo nível da camada Sea (oceano) e a camada de alto nível Containers.

Na parte de interação com o baixo nível que são os frameworks, bibliotecas e outras APIs de baixo nível da linguagem. A camada de Ship possui recursos, como bootstrap necessário para a aplicação, arquivos de configuração, registro de serviços e outros detalhes específicos.

Ela abriga também classes genéricas que são usadas dentro dos containers, como exceções, middlewares, classes de integração com serviços específicos, configurações compartilhadas e outros.

A camada de Ship ainda conta com classes de base. Essas classes podem ser estendidas dentro da camada Containers e permitem compartilhar código entre os diversos containers da aplicação.

Camada de containers

A camada de containers possui o código de alto nível da aplicação. Ela interage com a camada de nível intermediário (Ship).

Ela é responsável pela implementação da regra de negócio da aplicação. A ideia é que cada container contenha uma parte da regra de negócio. Ele deve receber a requisição e responder de acordo com cada UI (User Interface), que pode ser uma API, aplicação clássica web ou outra interface.

O ideal é que cada container esteja ligado a somente uma entidade/model da aplicação, mas nada impede que ele possua mais de um, porém quanto maior a quantidade de models, maior a complexidade do container, algo que o padrão estrutural tenta ao máximo evitar. Quanto mais simples os containers, maior a possibilidade de reutilizá-lo.

Componentes dos containers no padrão arquitetural Porto

Os containers são formados por componentes, cada um com sua responsabilidade. Eles podem ser componentes obrigatórios e opcionais.

O diagrama abaixo mostra como os componentes interagem dentro de um container:

Componentes da camada de containers da parquitetura porto

Os componentes pontilhados são opcionais enquanto os com linha contínua são obrigatórios. Note que temos os mesmos componentes do padrão MVC, veremos abaixo a responsabilidade deles no Porto.

Responsabilidade dos componentes no padrão arquitetural porto

Responsabilidade dos principais componentes:

  • Route - É o componente responsável por definir para cada caminho acessado qual será o controller responsável;
  • Controller - Recebe os dados da requisição, realiza a validação e autorização (em classe separada), envia para processamento em uma action e devolve a resposta apropriada;
  • Request - É o componente que obtém os dados de input da requisição. Pode também validar os dados e fazer autorização a partir deles. Deve sempre ser chamada a partir do controller;
  • Action - É responsável por receber os dados do controller, processar e devolver a ele. Ela está diretamente ligada a uma regra de negócio específica, se estivermos usando diagrama de caso de uso, podemos dizer que uma action é responsável por um caso de uso específico;
  • Task - Componente onde podemos colocar pequenas regras de negócio e que serão chamadas por diferentes actions do mesmo container ou de outros para evitar duplicidade;
  • Model - Usado para representar a estrutura no banco de dados. Ele não deve conter regras de negócio, apenas elementos referente ao mapeamento das tabelas e relacionamentos do banco de dados;
  • View - Elemento usado para separar o HTML da lógica da aplicação. Usada somente para UI (User Interface) web;
  • Transformers - Responsável por preparar os dados de saída quando trabalhamos com retornos para API. Sua principal vantagem é desacoplar o modo como os dados são retornados pelos modelos, permitindo a API retorna-los conforme sua necessidade;
  • Exceptions - Classes de exceções personalizadas, usadas para especificar as exceções que acontecem dentro do container;
  • Sub-Actions - Possui basicamente a mesma função das actions, porém é usada para eliminar duplicação de código. Ao invés repetir o mesmo código em duas Actions, usamos uma sub-action.

Existe também os componentes opcionais que podem ser usados conforme a necessidade do projeto.

Estrutura de pastas de container no padrão Porto

Abaixo é possível ver a estrutura de pastas de um container usando os principais componentes que conhecemos:

Container
	├── Actions
	├── Tasks
	├── Models
	├── Exceptions
	├── Tests
	│   ├── Unit
	│   └── Traits
	└── UI
	    ├── API
	    │   ├── Routes
	    │   ├── Controllers
	    │   ├── Requests
	    │   ├── Transformers
	    │   └── Tests
	    │       └── Functional
	    ├── WEB
	    │   ├── Routes
	    │   ├── Controllers
	    │   ├── Requests
	    │   ├── Views
	    │   └── Tests
	    │       └── Acceptance
	    └── CLI
	        ├── Routes
	        ├── Commands
	        └── Tests
	            └── Functional

Seções de containers

Os containers podem ser agrupados em seções. O principal objetivo delas é separar os containers de acordo com o contexto.

Cada seção de containers pode representar uma parte do seu sistema, o arquiteto tem a liberdade de escolher como criar as sessões e quais containers estarão dentro dela de acordo com sua aplicação.

Considerações finais

O padrão arquitetural Porto faz uso de vários conceitos que já são utilizados normalmente em aplicações back-end, o que facilita aos desenvolvedores compreenderem o que cada componente faz e também garante algumas características já comprovadas ao utilizar esses conceitos.

Você pode ler a documentação completa sobre o padrão Porto no seu repositório do Github.

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