Este capítulo possui uma versão mais recente:

Para quem só sabe usar martelo, todo problema é prego.
Abraham Maslow
Projetar sistemas em camadas é, provavelmente, a solução mais comum de design de arquitetura disponível. Aliás, tão comum ao ponto de muitos desenvolvedores entenderem que este é o único “estilo” arquitetural que existe.
0
Você concorda?x

A popularidade do estilo arquitetural baseado em camadas advém de sua simplicidade aparente e familiaridade. Há de se considerar também que ele é natural para a maioria das estruturas organizacionais e é “receita fácil” para “mania ágil” (não confundir com agilidade) de “sair programando”, repetindo o mais-do-mesmo.

Arquiteturas baseadas no estilo de camadas são tecnicamente particionadas (em oposição às arquiteturas particionadas por domínio). Ou seja, grupos de componentes, ao invés de serem estabelecidos pelo domínio, são formados por sua função técnica (como apresentação ou negócio)

Conceito fundamental

A ideia essencial desse estilo arquitetural é decompor os componentes de um sistema em uma pilha de camadas. Tradicionalmente, uma camada é autorizada a utilizar apenas a camada imediatamente abaixo. Uma camada inferior funciona como uma espécie de “máquina virtual” para a camada acima.

As camadas “mais baixas” são responsáveis por prover funções mais elementares que servem como “blocos de construção”, nas camadas “mais altas”, para a elaboração de funções mais sofisticadas.

Na sua forma mais restrita, este estilo arquitetural indica que uma determinada camada tenha acesso apenas a camada imediatamente abaixo, sendo que todas as demais ficam ocultas. Dessa forma, habilitam atributos de qualidade desejáveis como manutenabilidade, portabilidade e reuso, logo, promovendo o evolvability.

Como cada camada depende apenas da camada imediatamente abaixo desta, todas as camadas “mais baixas” podem ser substituídas ou “emuladas”, facilitando testes. Quanto mais camadas são adicionadas, maiores são as oportunidades de troca, entretanto, mais comuns são implicações para a performance.

Violações mais frequentes

As violações mais observadas nas implementações de arquiteturas baseadas no estilo arquitetural de camadas são 1) “pular” camadas, acessando camadas “mais baixas” diretamente; e 2) implementação “camadas compartilhadas” ou verticais
0
Alguma outra violação poderia ser mencionada aqui?x

Ambas violações, quando observadas, geralmente são bem justificadas. Entretanto, acabam comprometendo parte dos benefícios da adoção desse estilo arquitetural e são indícios de que, provavelmente, 1) outro estilo fosse mais adequado ; ou 2) houve exagero na definição de quantas camadas eram necessárias.

Camadas telefone-sem-fio

Um problema recorrente em muitas aplicações LOB (line-of-business) são implementações “ingênuas” do estilo arquitetural baseado em camadas, onde muitas não adicionam valor algum a solução.


Não são raras aplicações SPA, que interagem com APIs “pseudo-REST” CRUD, que acionam serviços de aplicação, que apenas traduzem objetos inputmodels em commands com propriedades idênticas, que são direcionado a um mecanismo de mensageria in-memory (como o MediatR em .NET), que aciona handlers, que materializam “entidades anêmicas”, que são, submetidas a persistência em repositórios (devidamente abstraídos em interfaces), que traduzem tais entidades em objetos de persistência, que são, enfim, salvos em um banco de dados.

A justificativa comum para tanta complexidade acidental é puritanismo ingênuo ou “movimento em manada” (a ilusão de que todo mundo faz assim) envolto na crença de que tais práticas diminuem o custo de manutenção quando, na verdade, fazem com que a simples inclusão de um campo de cadastro em um CRUD implique em modificações em diversos arquivos “explodindo” o changing coupling. Trata-se do architecture sinkhole anti-pattern. Parabéns a todos os envolvidos!
0
Você concorda?x

“Pular” camadas, acessando camadas “mais baixas” diretamente

Com alguma frequência, algumas implementações do estilo arquitetural em camadas “afrouxam” a restrição de que, em qualquer nível, apenas a “camada imediatamente abaixo” pode ser acessada diretamente. A justificativa geralmente tem relação com a performance.


Os principais pontos negativos dessa flexibilização são o potencial aumento da complexidade de implementação na camada que está violando a restrição, por estar lidando com elementos mais fundamentais, e o aumento do acoplamento aferente da camada do nível mais baixo que está sendo acessada “indevidamente”, tornando-a mais difícil de evoluir. A “camada violadora”, por sua vez, tem seu acoplamento eferente aumentado, tornando-se mais instável (passível de falhas) e “presa” a uma determinada configuração ou plataforma operacional.
0
Algo mais?x

Uma aplicação escrita em .NET ou Java, por exemplo, ao fazer uso direto de um recurso do sistema operacional, torna-se menos “portável”.

“Camadas compartilhadas” ou verticais

Outra violação comum são as “camadas compartilhadas” ou verticais, diretamente acionadas por todas as demais camadas da solução. Geralmente, essas “camadas” fornecem features genéricas e úteis, como para instrumentação ou segurança.

Na prática, essas implementações verticais não são “camadas” de fato. Ou, ainda, em cenários mais complexos, habilitam uma visão arquitetural 2D, com uma dimensão de negócios e outra técnica, o que pode ser interessante. De qualquer forma, é importante destacar a explosão do acoplamento aferente nas camadas verticais.

Camadas comuns em aplicações LOB (line-of-business)

Aplicações de negócios desenvolvidas com arquiteturas baseadas em camadas geralmente apresentam variações de quatro camadas lógicas: 1) apresentação; 2) negócios; 3) persistência; e 4) banco de dados. Algumas vezes, as camadas de persistência e banco de dados são “mescladas” e ampliadas para uma descrição mais genérica, como “infraestrutura”. Outras vezes, a camada de negócios é “fragmentada” em “aplicação” e “domínio”.

O curioso, entretanto, é que, modernamente, essa composição não é fiel a ideia original do estilo em camadas no sentido de que os “níveis mais baixos” fornecem, necessariamente, base operacional para construção de elementos cada vez mais elaborados nos “níveis mais altos”. Talvez essa seja a razão para o aparente “descolamento” desse estilo com soluções contemporâneas.
0
Você concorda?x

Um jeito (nem tão) antigo de fazer software LOB

Até bem pouco tempo, a “análise de sistemas” consistia em descobrir quais relatórios e consultas um software precisaria produzir. Daí, se inferia que dados seriam necessários e que “cadastros” teriam que ser elaborados.


Nesses tempos, a implementação de um sistema de software começava com a modelagem do banco de dados, somente depois eram implementadas telas de cadastro para, finalmente, elaborar relatórios. Não eram incomuns ferramentas “geradoras” de telas de cadastro (como Magic, Genero e afins) e outras para elaboração de relatórios (como Crystal Reports).
0
Você concorda com essa afirmação? Há algo a ponderar aqui?x


Nessa “visão antiga”, o banco de dados é o rei. Aliás, seguindo essa linha, é natural enxergar o banco como lugar ideal para implementar lógica de negócio. Há um bocado de “gente grande” que ainda pensa e desenvolve software desse jeito, procurando apenas formas de evoluir no frontend para criar “telinhas mais bonitas”.
0
Você concorda?x

As camadas de uma aplicação são ótimo registro para o architecture haiku.

Conway, outra vez!

As arquiteturas de 4 (as vezes 3) camadas, tão comuns em aplicações LOB, são, também expressão da lei de Conway.

Qualquer empresa que projeta um sistema, inevitavelmente, produz um projeto cuja a estrutura é uma cópia da estrutura de comunicação da organização. – Melvin Conway

Na maioria das organizações é comum encontrar times de desenvolvedores especialistas em frontend (UI e UX), backend, especialistas de negócio e DBAs. Essa “estrutura” da organização se encaixa naturalmente no modelo em camadas adotado em boa parte do mercado, se tornando assim, natural.

A implementação de um estilo arquitetural que não seja o baseado em camadas implica na revisão da organização da empresa, caso essa esteja organizada em times funcionais.

Implicações para o Deploy

Embora o estilo arquitetural em camadas preconize a independência de cada camada, com vistas a melhoria do evolvability, não é difícil perceber que esta “promessa” não se cumpre, com base na forma como ocorrem os deploys das aplicações.

Não raro, as camadas de apresentação, negócios e persistência formam um bloco único de deploy com acoplamento eferente para o banco de dados, que segue gestão independente.

Outras vezes, a camada de apresentação é segmentada no deploy dando autonomia para atualizações e implementações de “perfumarias estéticas” (reproduzindo aqui comportamento desrespeitoso e míope, frequentemente observado no mercado).

Finalmente, há ainda cenários, geralmente em aplicações menores, onde todas as camadas formam um único bloco de deploy.

Camadas abertas e fechadas

Eventualmente, uma camada pode dispensar as features fornecidas por aquela, ou aquelas, imediatamente abaixo. Neste caso, precisa “pular” estas camadas, acessando diretamente aquela que provê aquilo de que necessita.

Idealmente, esses “pulos” precisam ser projetados, indicando as camadas dispensáveis como “abertas”. Enquanto aquelas que não podem ser ignoradas devem ser apontadas como “fechadas”.

Aplicações que fornecem APIs para consumo externo, por exemplo, porém que dispensam o uso na própria camada de apresentação, mantém a camada das APIs abertas.

Outra decisão que “abre” algumas camadas são implementações do padrão fast-lane reader, onde a camada de apresentação faz queries diretamente contra o banco de dados, tentando maximizar performance.

As decisões de quais camadas devem ser abertas, e os porquês, devem ser registradas em ADRs. O monitoramento ativo das ligações entre as camadas é uma excelente base fitness functions.
0
Você concorda?x

Para cada jornada, as ferramentas certas

Não há problema na maioria dos sistemas serem projetados utilizando arquiteturas baseadas em camadas. O que seria problema é essa ser a escolha padrão por desconhecimento de outras alternativas.
0
Você concorda?x

Utilizar “camadas” é um “começo seguro” quando arquitetos ainda estão incertos quanto a qual seria o padrão arquitetural adequado, mas algum código precisa ser iniciado. Entretanto, para garantir que a migração seja possível, é importante manter as camadas “fechadas” pelo máximo de tempo possível.
0
Você concorda?x

// TODO

Antes de avançar para o próximo capítulo, recomendo algumas reflexões:

  • Você já lidou, ou está lidando, com arquiteturas “viciadas” pela implementação do sinkhole anti-pattern.
  • Você já lidou com arquiteturas baseadas em camadas “exóticas” em LOB? Como elas eram?
  • Você enfrenta problemas de performance em sua aplicação decorrentes de decisões de manter todas as camadas fechadas?

Referências bibliográficas

MUNROE, Randall. Abstraction Disponível em: https://xkcd.com/676/. Acesso em: 08 mai. 2021.

Compartilhe este capítulo:

Compartilhe:

Comentários

Participe da construção deste capítulo deixando seu comentário:

Inscrever-se
Notify of
guest
0 Comentários
Feedbacks interativos
Ver todos os comentários

Fundador e CEO da EximiaCo, atua como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

Mentoria

para arquitetos de software

Imersão, em grupo, supervisionada por Elemar Júnior, onde serão discutidos tópicos avançados de arquitetura de software, extraídos de cenários reais, com ênfase em systems design.

Consultoria e Assessoria em

Arquitetura de Software

EximiaCo oferece a alocação de um Arquiteto de Software em sua empresa para orientar seu time no uso das melhores práticas de arquitetura para projetar a evolução consistente de suas aplicações.

ElemarJúnior

Fundador e CEO da EximiaCo, atua como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

+55 51 99942-0609 |  contato@eximia.co

+55 51 99942-0609  contato@eximia.co

0
Quero saber a sua opinião, deixe seu comentáriox
()
x