E Ottaviani Aragão Blog Projetos Sobre Mim

Arquitetura e Camadas de abstração — Uma proposta para Front End — Final— Implementação

Chega de bullshitagem né, só falei, desenhei e filosofei sobre uma tal forma de separar a parte do todo e como relacioná-las. Não que estas partes não sejam importantes, na real, acredito que são fundamentais para o sucesso de um projeto com manutenção saudável. Porém, acho que o ideal é que a tese seja comprovada de maneira empírica quando possível.

Então a implementação defende alguns princípios, estes foram retirados / absorvidos de uma série de conceitos, arquiteturas, metodologias e portanto é uma junção de todo esse aprendizado somado com uma parte extremamente importante, a experiência.

Considero a experiência de extrema importância porque só assim você verá de fato as vantagens e as desvantagens deixando de lado a parte emocional.

Os Princípios

  1. Criar as abstrações de maneira desacoplada da implementação final, sem considerar a tecnolgia específica ou framework que será usado, e assim deixar a aplicação mais desacoplada, diminuindo os contextos onde o framework atua.
  2. Trabalhar com a restrição de limite das abstrações através de domínios, e no caso do front, os domínios seriam as páginas.
  3. As interações entre as partes componentizadas que precisam ser compartilhadas, deveriam ser centralizadas através de uma store, utilizando-se de casos de uso para centralizar as regras da aplicação.
  4. Os tratamentos de dados feitos de maneira separada e distante do componente por este estar mais acoplado ao framework, então delegamos para uma camada de serviços e entidades a manutenção da estrutura de dados a ser consumida bem como a conversão de valores.
  5. Criar a possibilidade de desplugar de maneira prática áreas que podem ser descontinuadas ( Páginas ) ou extraídas para serem utilizadas de maneira apartada ( UI-system ).
  6. Por final, obviamente facilitar/possibilitar a extensão do projeto com novas abstrações e pastas de acordo com as necessidades, especificidades do framework que esteja utilizando.

Eu acredito que nenhuma arquitetura tem vida própria, ela depende de um esforço cognitivo e intelecutal recorrente nosso para adaptá-lo com inúmeras iterações e refatorações para se adequar às exigências atuais, no entanto, acredito que se ela for simples e direta o suficiente, essa evolução e transição deveria ser superficial e mínima e não na sua mudança total e reconstrução.

A especificação da demonstração

A aplicação obviamente precisa ser simples para que seja mais visível seu valor, se eu pensasse em uma aplicação complexa, primeiro demoraria muito para fazer esse post, segundo que você poderia focar em coisas que acabam saindo do princípio original, e como todo projeto, podem existir códigos mal escritos e portanto você teria o ímpeto de invalidar a solução como um todo, porque cognitivamente é mais fácil para o seu cérebro, dado esse disclaimer, bora para a especificação.

  1. A aplicação tem apenas uma página, home, e lista de cards de produtos consumidos através de uma api requisitada no page load, cada um com suas informações específicas. A única interação possível do usuário é a adição do produto ao carrinho.
  2. Ao adicionar ao carrinho, um contador no header deve mostrar a quantidade de itens adicionada até o momento.
  3. O sistema admite 2 tipos de usuário, todos que acessam a página iniciam como um usuário comum. O outro usuário é um usuário premium.
  4. A diferença dos dois usuários é que o comum pode adicionar até no máximo 5 itens no carrinho, a partir deste número ele é bloqueado de adicionar mais e é avisado que para continuar pode limpar o carrinho e começar a adicionar novos produtos ou pode optar por fazer o upgrade de usuário, continuando dali até quantos produtos quiser adicionar.

É uma aplicação quase inútil sob perspectiva de produto, mas existem elementos técnicos ali que estão sim presentes nas aplicações que trabalhamos, regras, requisições, interações de usuário, o que é suficiente para testar a arquitetura e esta mostrar um pouco da sua cara.

A Implementação

Estou usando Next.js, mas essa é a parte menos importante. Não achei um state managment system fácil e plug and play pra usar, então to usando um que desenvolvi e estou para publicar no npm em breve, como não consigo usar as dependencias referenciando o github no stackblitz, acabei botando dentro de uma pasta que chamei de packages , mas não existiria em um projeto real =).

https://medium.com/media/925286dda0533e1a122c323a4f9bfcdd/href

O Relacionamento e as responsabilidades

A lógica é a seguinte:

  1. Um componente de listagem faz uma requisição utilizando a camada de serviços e essa se utiliza da Entidade produtopara definir quais propriedades, qual a estrutura do objeto e transformações / formatações os campos terão, para só então devolver ao componente os dados no seu formato já preparado.
  2. O componente então utiliza os listeners do framework para ouvir a interação do usuário e faz a atualização da UI, estas são suas principais responsabilidades. Ao ouvir o click de adicionar ao carrinho, o componente comunica com a store, onde estão centralizadas as regras da aplicação e o estado atual do sistema, disparando um evento e dizendo qual ação e qual produto foi adicionado.
  3. A store então atualiza o estado atual do sistema executando uma função que representa aquele caso de uso que irá atualizar o estado do sistema, e logo em seguida notifica à todos os componentes que estão inscritos, estes receberão o estado atual.
  4. A tarefa do componente é verificar dado o estado atual o que deve ser feito na UI, no caso de adição de mais de 5 itens para o usuário normal o componente modal que está inscrito na Store deve aparecer e fazer o mesmo papel do componente Card, atualizar a UI e ouvir eventos do usuário para a nova ação, seja ela de limpar os produtos do carrinho, seja o upgrade de usuário.

É isso… Finito.