Arquiteturas escaláveis para SPAs com Angular

Douglas Caina
CWI Software
Published in
4 min readNov 28, 2017

Programar com componentes é muito produtivo, surge uma task, você cria um novo componente pelo cli,joga as regras dentro do html, faz o bind com 2way data bind e vai pra próxima task. Assim, nascem aqueles projetos indomáveis que vão nos assombrar a cada nova sprint.👻

Para resolver alguns problemas de arquitetura de uma aplicação SPA, podemos utilizar a técnica de Statefull e Stateless components, vamos exemplificar isso construindo um pequeno app que calcula a diferença entre tempos.

Applicação de exemplo

Statefull e Stateless components

Resumindo: Statefull são componentes que contém a lógica de negócio. Em geral não possuem estilos, apenas a construção dos componentes de tela, já os stateless são components de tela e não possuem lógica de negócio, são utilizados para montar as telas como blocos de lego, este artigo explica mais a fundo este tema.

Indo para a arquitetura da nossa aplicação, quebramos ela da seguinte maneira:

  • Scenes: nossos componentes Statefull, cada componente é uma tela do sistema
  • Scenes/Componentes: Componentes de tela que não são reaproveitados fora da cena
  • Components: nossos componentes genéricos usados entre as Cenas

Perceba que Time-sheet(scene/time/time-sheet)agrupa os componentes que montam nossa tela principal, enquanto time-history é uma tela que lista os históricos gerados pelo app, sendo assim, são componentes Statefull importando componentes de tela da pasta components.

Em time-sheet instanciamos o componente app-time-line, que possui dois inputs, a hora de início a hora de fim e emite um evento ao clicar em “Ok”. Este evento é capturado pelo nosso componente de lógica time-sheet, que manipula estes valores resultando em um valor em horas da diferença, este valor em hora é disparado como outro evento, que por sua vez é capturado pelo componente que exibe o total de horas app-time-result, o qual arredonda este valor e formata ele em um formato de “HH:mm”.

Percebeu que cada componente trabalhou de forma autônoma? Sem a necessidade do componente time-sheet passar uma referência de um objeto para os demais, a vantagem desta técnica, é que quando desenvolvemos o botão de “summarize”, o resultado do cálculo emite o mesmo evento das linhas de tempo, nos dando a liberdade de refatorar este componente como bem queremos pois ele não possui nenhum vínculo com o componente pai!

time-sheet.component.html

Vamos rever o que este componente está fazendo:

  • <app-card> é um componente Stateless que monta a tela na forma do cartão.
  • <app-time-result> está recebendo um Observable com o pipeline async que quando recebe um evento, repassa para o componente como input.
  • <div class=”card-list”> #timeLines é usado para passar a referencia desta div para o componente poder instanciar novos <app-time-line> no componente Statefull

Observe que nosso componente de Time-sheet está apenas agregando outros componentes e delegando ações para eles, mantendo suas lógicas desacopladas e reativas. Além disso, conseguimos ter uma arquitetura “Flat”, ou seja, poucas camadas de componentes.

fluxo de vida dos eventos de contabilização de tempo

Mas o que é Programação Reativa?

Em poucas palavras, todos os componentes que estavam esperando ações por listners são reativos!

Programação reativa é programar com fluxos(streams) de dados assíncronos. Assíncrono significa que não se realiza ao mesmo tempo ou no mesmo ritmo de desenvolvimento (em relação a outra coisa).

Nosso componentes são independentes e não compartilham o mesmo ciclo de vida que seus componentes irmãos, podem ser reaproveitados fora deste eco-sistema de calculo de tempo e ainda conseguem delegar responsabilidades de maneira coerente.

Revisando

Separando nossos componentes entre apresentação e lógica, nos tornamos mais eficientes e escaláveis, temos mais confiança na hora de refatorar uma tela e temos como melhorar a performance de renderização deles mudando o modo do mesmo.

Um pouco sobre minha experiência desta forma de desenvolvimento: Trabalhei em um projeto em que os seus componentes não se distinguiam entre Stateless e Statefull, cada componente controla os dados que recebia e obedeciam lógicas de negócio vinculadas à tela em que estavam inseridos. Reaproveitar um componente fora do ciclo de vida que ele havia sido originalmente desenhado era muito complexo e muitas vezes não valia a pena. Além do pouco reaproveitamento de código, debugalos era muito complexo pois a lógica fica distribuído entre os componentes.

Para este exemplo usamos Angular, mas poderia ter sido feito com qualquer Framework ou Library, se tiver alguma sugestão ou duvida deixe um comentário!

--

--