{"id":1633,"date":"2021-05-09T08:13:41","date_gmt":"2021-05-09T11:13:41","guid":{"rendered":"https:\/\/elemarjr.com\/arquiteturadesoftware\/?p=1633"},"modified":"2024-01-12T18:14:31","modified_gmt":"2024-01-12T21:14:31","slug":"projetando-software-em-camadas","status":"publish","type":"volume-1","link":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/","title":{"rendered":"Cap 3.1 Projetando software em camadas"},"content":{"rendered":"<p><strong>Abstrair os os componentes de um sistema em camadas \u00e9 algo comum e, at\u00e9 certo ponto, inevit\u00e1vel. <\/strong>Identificamos rapidamente partes dos sistemas com &#8220;externalidade maior&#8221;, como em interfaces com usu\u00e1rios ou integra\u00e7\u00f5es. Com menos externalidade, temos as partes contendo a &#8220;intelig\u00eancia e persist\u00eancia&#8221; da solu\u00e7\u00e3o. Dessa &#8220;recorr\u00eancia&#8221;, provavelmente, emerge a popularidade do estilo arquitetural baseado em camadas.<\/p>\nO estilo arquitetural em camadas \u00e9, provavelmente, a solu\u00e7\u00e3o mais comum de <em>design<\/em> de arquitetura dispon\u00edvel. Ali\u00e1s, t\u00e3o comum ao ponto de muitos desenvolvedores entenderem que este \u00e9 o \u00fanico caminho arquitetural que existe.\n<hr \/>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/imgs.xkcd.com\/comics\/abstraction.png\" width=\"365\" height=\"365\" \/><\/p>\n<p>Arquiteturas baseadas no estilo de camadas s\u00e3o tecnicamente particionadas (em oposi\u00e7\u00e3o \u00e0s arquiteturas particionadas por dom\u00ednio). Ou seja, grupos de componentes, ao inv\u00e9s de serem estabelecidos pelo dom\u00ednio, s\u00e3o formados por sua fun\u00e7\u00e3o t\u00e9cnica (como apresenta\u00e7\u00e3o ou neg\u00f3cio).<\/p>\n<div class=\"card-insight\" style=\"background-color: #f0f0f0; width: 100%; padding: 35px 30px 30px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px; box-shadow: 0px 4px 0px 0px #dddddd;\">\r\n<p style=\"font-size: 24px; font-weight:bold; line-height: 28px; font-family: Montserrat;\">'Layer' e 'Tier'<\/p>\r\n<\/p>\n<p>O termo camada \u00e9 frequentemente associado a dois conceitos distintos (em ingl\u00eas): <em>layer\u00a0<\/em>e\u00a0<em>tier<\/em>.<\/p>\n<p>Uma\u00a0<em>layer\u00a0<\/em>\u00e9 uma separa\u00e7\u00e3o l\u00f3gica de c\u00f3digo, geralmente relacionada a algum aspecto funcional. Idealmente a comunica\u00e7\u00e3o entre camadas deve acontecer explicitamente e de maneira pouco acoplada.<\/p>\n<p>Uma\u00a0<em>tier\u00a0<\/em>\u00e9 uma separa\u00e7\u00e3o f\u00edsica aplicada a uma camada. Essa &#8220;separa\u00e7\u00e3o&#8221; f\u00edsica pode indicar um servidor distinto ou processo dedicado.<\/p>\n<p>Nesse cap\u00edtulo, quando nos referimos a camadas, tratamos de\u00a0<em>layers.<\/em><\/p>\n<p><\/div>\n<h2>Conceito fundamental<\/h2>\n<p>A ideia essencial desse estilo arquitetural \u00e9 decompor os componentes de um sistema em uma pilha de camadas. <strong>Tradicionalmente, uma camada \u00e9 autorizada a utilizar apenas a camada imediatamente abaixo.<\/strong> Uma camada inferior funciona como uma esp\u00e9cie de &#8220;m\u00e1quina virtual&#8221; para a camada acima.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-1579 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_00.png\" alt=\"\" width=\"411\" height=\"246\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_00.png 816w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_00-300x179.png 300w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_00-768x459.png 768w\" sizes=\"(max-width: 411px) 100vw, 411px\" \/><\/p>\n<p>As camadas &#8220;mais baixas&#8221; s\u00e3o respons\u00e1veis por prover fun\u00e7\u00f5es mais elementares que servem como &#8220;blocos de constru\u00e7\u00e3o&#8221;, nas camadas &#8220;mais altas&#8221;, para a elabora\u00e7\u00e3o de fun\u00e7\u00f5es mais sofisticadas.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-1582 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_01.png\" alt=\"\" width=\"411\" height=\"184\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_01.png 808w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_01-300x134.png 300w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_01-768x344.png 768w\" sizes=\"(max-width: 411px) 100vw, 411px\" \/><\/p>\n<p>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\u00e1veis como manutenabilidade, portabilidade e reuso, logo, promovendo o <em>evolvability<\/em>.<\/p>\n<div class=\"nota-insight\">\r\n<table class=\"tabelainsight\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img loading=\"lazy\" decoding=\"async\" class=\"img-insight\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img loading=\"lazy\" decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/> Sempre que uma camada \u00e9 inserida na pilha, oferece um n\u00edvel de abstra\u00e7\u00e3o mais alto as funcionalidades disponibilizadas nas camadas mais baixas.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<p>Como cada camada depende apenas da camada imediatamente abaixo desta, todas as camadas &#8220;mais baixas&#8221; podem ser substitu\u00eddas ou &#8220;emuladas&#8221;, facilitando testes. <strong>Quanto mais camadas s\u00e3o adicionadas, maiores s\u00e3o as oportunidades de troca, entretanto, mais comuns s\u00e3o implica\u00e7\u00f5es para o desempenho.<\/strong><\/p>\n<h2>Filosofia de <em>design<\/em><\/h2>\n<p><strong>Atentando ao estilo sob a perspectiva de design, a separa\u00e7\u00e3o de um <em>software <\/em>em camadas revela, acima de tudo, uma estrat\u00e9gia de modulariza\u00e7\u00e3o<\/strong>. As camadas &#8220;mais baixas&#8221; recebem &#8220;responsabilidades&#8221; mais primitivas. Enquanto as camadas &#8220;mais altas&#8221; ficam respons\u00e1veis por &#8220;responsabilidades mais complexas&#8221;, que podem ser cumpridas, gra\u00e7as a combina\u00e7\u00e3o das camadas em n\u00edvel mais baixo.<\/p>\n<p>O n\u00edvel de &#8220;acoplamento para desenvolvimento e operacional&#8221; das camadas fica, ent\u00e3o determinado pela estrat\u00e9gia de conex\u00e3o entre as camadas. Cada camada pode fornecer um ou mais componentes, cada componente pode se ligar, com componentes de camadas superiores ou inferiores, com conectores diversos (exemplo, requisi\u00e7\u00f5es HTTP ou simples chamadas de m\u00e9todos, dependendo da separa\u00e7\u00e3o ou n\u00e3o em <em>tiers<\/em>).<\/p>\n<div class=\"nota-link\">\r\n<table class=\"tabelalink\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img loading=\"lazy\" decoding=\"async\" class=\"img-insight\" src=\"\/arquiteturadesoftware\/wp-content\/uploads\/2022\/05\/link.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img loading=\"lazy\" decoding=\"async\" class=\"nota-img\" src=\"\/arquiteturadesoftware\/wp-content\/uploads\/2022\/05\/link.png\" alt=\"\" width=\"70\" height=\"70\" \/>\r\n<p style=\"font-size: 22px; font-weight: bold; line-height: 26px; font-family: Montserrat; color: #432b75; margin-bottom: 5px;\">Tipos de Acoplamento<\/p>\r\n<p style=\"font-size: 16px; font-weight: Regular; line-height: 20px; font-family: Roboto; color: #45365d; margin-bottom: 0px;\">Controlar o acoplamento \u00e9 sempre aspecto central para qualquer discuss\u00e3o arquitetural. Quer relembrar os tipos de acoplamento, conforme classifica\u00e7\u00e3o de Nygard?<\/p>\r\n<a class=\"botao-livro\" href=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/entendendo-e-convivendo-com-o-acoplamento\/#Tipos_de_acoplamento\" target=\"_blank\" rel=\"noopener\">Acessar t\u00f3pico<\/a><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<div class=\"nota-livro\">\r\n<table class=\"tabelalivro\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-livro-coluna-1\" valign=\"top\"><img decoding=\"async\" src=\"https:\/\/programacao-orientada-a-objetos.online\/wp-content\/uploads\/2021\/09\/livro-poo.png\" alt=\"\" width=\"150\" \/><\/td>\r\n<td class=\"nota-livro-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"https:\/\/programacao-orientada-a-objetos.online\/wp-content\/uploads\/2021\/09\/livro-poo.png\" alt=\"\" width=\"150\" \/>\r\n<p style=\"font-size: 24px; font-weight: bold; color: #4c4c4c; line-height: 1.0; font-family: Lufga; margin-bottom: 10px;\">Lidando com falhas para prevenir erros e defeitos<\/p>\r\n<p style=\"font-size: 20px; font-weight: bold; color: #4c4c4c; line-height: 1.1; font-family: Lufga; margin-bottom: 10px;\">Programa\u00e7\u00e3o Orientada a Objetos<\/p>\r\nA &#8220;externalidade&#8221; de um componente, ou seja, a camada em que ele se encontra, \u00e9 um dos fatores que determina, tamb\u00e9m, o quanto excepcional uma falha deve ser considerada. Esse cap\u00edtulo do livro &#8220;Programa\u00e7\u00e3o Orientada a Objetos&#8221; trata exatamente dessa caracter\u00edstica.\r\n<p><a class=\"botao-livro\" href=\"https:\/\/programacao-orientada-a-objetos.online\/lidando-com-falhas-para-previnir-erros-e-defeitos-capitulo-3-v-1-0\/\" target=\"_blank\" rel=\"noopener\">Ler cap\u00edtulo<\/a><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<h2>Camadas abertas e fechadas<\/h2>\n<p>Eventualmente, uma camada pode dispensar as <em>features<\/em> fornecidas por aquela, ou aquelas, imediatamente abaixo. Neste caso, precisa \u201cpular\u201d estas camadas, acessando diretamente aquela que prov\u00ea aquilo de que necessita.<\/p>\n<p>Idealmente, esses \u201cpulos\u201d precisam ser projetados, indicando as camadas dispens\u00e1veis como \u201cabertas\u201d. Enquanto aquelas que n\u00e3o podem ser ignoradas devem ser apontadas como \u201cfechadas\u201d.<\/p>\n<p>Aplica\u00e7\u00f5es que fornecem APIs para consumo externo, por exemplo, por\u00e9m que dispensam o uso na pr\u00f3pria camada de apresenta\u00e7\u00e3o, mant\u00e9m a camada das APIs abertas.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1624 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camadas_open.png\" alt=\"\" width=\"337\" height=\"292\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camadas_open.png 727w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camadas_open-300x260.png 300w\" sizes=\"(max-width: 337px) 100vw, 337px\" \/><\/p>\n<p>Outra decis\u00e3o que \u201cabre\u201d algumas camadas s\u00e3o implementa\u00e7\u00f5es do padr\u00e3o <em>fast-lane reader<\/em>, onde a camada de apresenta\u00e7\u00e3o faz <em>queries<\/em> diretamente contra o banco de dados, tentando maximizar performance.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1625 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camadas_open_2.png\" alt=\"\" width=\"337\" height=\"233\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camadas_open_2.png 727w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camadas_open_2-300x207.png 300w\" sizes=\"(max-width: 337px) 100vw, 337px\" \/><\/p>\nAs decis\u00f5es de quais camadas devem ser abertas, e os porqu\u00eas, devem ser registradas em ADRs. O monitoramento ativo das liga\u00e7\u00f5es entre as camadas \u00e9 uma excelente base <em>fitness functions<\/em>.\n<hr \/>\n<h2>Viola\u00e7\u00f5es mais frequentes<\/h2>\nAs viola\u00e7\u00f5es mais observadas nas implementa\u00e7\u00f5es de arquiteturas baseadas no estilo arquitetural de camadas s\u00e3o 1) &#8220;pular&#8221; camadas, acessando camadas &#8220;mais baixas&#8221; diretamente; e 2) implementa\u00e7\u00e3o &#8220;camadas compartilhadas&#8221; ou verticais\n<hr \/>\n<p>Ambas viola\u00e7\u00f5es, quando observadas, geralmente s\u00e3o bem justificadas. Entretanto, acabam comprometendo parte dos benef\u00edcios da ado\u00e7\u00e3o desse estilo arquitetural e s\u00e3o ind\u00edcios de que, provavelmente, 1) outro estilo fosse mais adequado ; ou 2) houve exagero na defini\u00e7\u00e3o de quantas camadas eram necess\u00e1rias.<\/p>\n<div class=\"card-insight\" style=\"background-color: #f0f0f0; width: 100%; padding: 35px 30px 30px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px; box-shadow: 0px 4px 0px 0px #dddddd;\">\r\n<p style=\"font-size: 24px; font-weight:bold; line-height: 28px; font-family: Montserrat;\">Camadas telefone-sem-fio<\/p>\r\nUm problema recorrente em muitas aplica\u00e7\u00f5es <em>LOB (line-of-business)<\/em> s\u00e3o implementa\u00e7\u00f5es &#8220;ing\u00eanuas&#8221; do estilo arquitetural baseado em camadas, onde muitas n\u00e3o adicionam valor algum a solu\u00e7\u00e3o.<\/p>\n<hr \/>\n<p>N\u00e3o s\u00e3o raras aplica\u00e7\u00f5es SPA, que interagem com APIs &#8220;pseudo-REST&#8221; CRUD, que acionam servi\u00e7os de aplica\u00e7\u00e3o, que apenas traduzem objetos <em>inputmodels <\/em>em <em>commands <\/em>com propriedades id\u00eanticas, que s\u00e3o direcionado a um mecanismo de mensageria in-memory (como o MediatR em .NET), que aciona <em>handlers, <\/em>que materializam &#8220;entidades an\u00eamicas&#8221;, que s\u00e3o, submetidas a persist\u00eancia em reposit\u00f3rios (devidamente abstra\u00eddos em interfaces), que traduzem tais entidades em objetos de persist\u00eancia, que s\u00e3o, enfim, salvos em um banco de dados.<\/p>\n<p>A justificativa comum para tanta complexidade acidental \u00e9 puritanismo ing\u00eanuo ou &#8220;movimento em manada&#8221; (a ilus\u00e3o de que todo mundo faz assim) envolto na cren\u00e7a de que tais pr\u00e1ticas diminuem o custo de manuten\u00e7\u00e3o quando, na verdade, fazem com que a simples inclus\u00e3o de um campo de cadastro em um CRUD implique em modifica\u00e7\u00f5es em diversos arquivos &#8220;explodindo&#8221; o <em>changing coupling<\/em>. Trata-se do <em>architecture sinkhole anti-pattern.<\/em> Parab\u00e9ns a todos os envolvidos!<\/div>\n<h4>&#8220;Pular&#8221; camadas, acessando camadas &#8220;mais baixas&#8221; diretamente<\/h4>\n<p>Com alguma frequ\u00eancia, algumas implementa\u00e7\u00f5es do estilo arquitetural em camadas &#8220;afrouxam&#8221; a restri\u00e7\u00e3o de que, em qualquer n\u00edvel, apenas a &#8220;camada imediatamente abaixo&#8221; pode ser acessada diretamente. A justificativa geralmente tem rela\u00e7\u00e3o com o desempenho.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1583\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_02.png\" alt=\"\" width=\"337\" height=\"266\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_02.png 696w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_02-300x237.png 300w\" sizes=\"(max-width: 337px) 100vw, 337px\" \/><\/p>\n<hr \/>\nOs principais pontos negativos dessa flexibiliza\u00e7\u00e3o s\u00e3o o potencial aumento da complexidade de implementa\u00e7\u00e3o na camada que est\u00e1 violando a restri\u00e7\u00e3o, por estar lidando com elementos mais fundamentais, e o aumento do acoplamento aferente da camada do n\u00edvel mais baixo que est\u00e1 sendo acessada &#8220;indevidamente&#8221;, tornando-a mais dif\u00edcil de evoluir. <strong>A &#8220;camada violadora&#8221;, por sua vez, tem seu acoplamento eferente aumentado, tornando-se mais inst\u00e1vel<\/strong> (pass\u00edvel de falhas) e &#8220;presa&#8221; a uma determinada configura\u00e7\u00e3o ou plataforma operacional.\n<hr \/>\n<p>Uma aplica\u00e7\u00e3o escrita em .NET ou Java, por exemplo, ao fazer uso direto de um recurso do sistema operacional, torna-se menos &#8220;port\u00e1vel&#8221;.<\/p>\n<h4>&#8220;Camadas compartilhadas&#8221; ou verticais<\/h4>\n<p>Outra viola\u00e7\u00e3o comum s\u00e3o as &#8220;camadas compartilhadas&#8221; ou verticais, diretamente acionadas por todas as demais camadas da solu\u00e7\u00e3o. Geralmente, essas &#8220;camadas&#8221; fornecem <em>features <\/em>gen\u00e9ricas e \u00fateis, como para instrumenta\u00e7\u00e3o ou seguran\u00e7a.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1606 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_03.png\" alt=\"\" width=\"442\" height=\"264\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_03.png 814w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_03-300x179.png 300w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_03-768x459.png 768w\" sizes=\"(max-width: 442px) 100vw, 442px\" \/><\/p>\n<p>Na pr\u00e1tica, essas implementa\u00e7\u00f5es verticais n\u00e3o s\u00e3o &#8220;camadas&#8221; de fato. Ou, ainda, e<strong>m cen\u00e1rios mais complexos, habilitam uma vis\u00e3o arquitetural 2D, com uma dimens\u00e3o de neg\u00f3cios e outra t\u00e9cnica, o que pode ser interessante.<\/strong> De qualquer forma, \u00e9 importante destacar a explos\u00e3o do acoplamento aferente nas camadas verticais.<\/p>\n<h2>Camadas em aplica\u00e7\u00f5es LOB (<em>line-of-business<\/em>)<\/h2>\n<p>Aplica\u00e7\u00f5es de neg\u00f3cios desenvolvidas com arquiteturas baseadas em camadas geralmente apresentam varia\u00e7\u00f5es de quatro camadas l\u00f3gicas: 1) apresenta\u00e7\u00e3o; 2) neg\u00f3cios; 3) persist\u00eancia; e 4) banco de dados. Algumas vezes, as camadas de persist\u00eancia e banco de dados s\u00e3o &#8220;mescladas&#8221; e ampliadas para uma descri\u00e7\u00e3o mais gen\u00e9rica, como &#8220;infraestrutura&#8221;. Outras vezes, a camada de neg\u00f3cios \u00e9 &#8220;fragmentada&#8221; em &#8220;aplica\u00e7\u00e3o&#8221; e &#8220;dom\u00ednio&#8221;.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1608 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camadas_04.png\" alt=\"\" width=\"337\" height=\"235\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camadas_04.png 696w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camadas_04-300x209.png 300w\" sizes=\"(max-width: 337px) 100vw, 337px\" \/><\/p>\nO curioso, entretanto, \u00e9 que, modernamente, essa composi\u00e7\u00e3o n\u00e3o \u00e9 fiel a ideia original do estilo em camadas no sentido de que os &#8220;n\u00edveis mais baixos&#8221; fornecem, necessariamente, base operacional para constru\u00e7\u00e3o de elementos cada vez mais elaborados nos &#8220;n\u00edveis mais altos&#8221;. Talvez essa seja a raz\u00e3o para o aparente &#8220;descolamento&#8221; desse estilo com solu\u00e7\u00f5es contempor\u00e2neas.\n<hr \/>\n<div class=\"nota-livro\">\r\n<table class=\"tabelalivro\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-contribuicao-2\">\r\n<p style=\"font-size: 22px; font-weight: bold; color: #4c4c4c; line-height: 1.1; font-family: Montserrat; margin-bottom: 10px;\">A reminder on Three\/Multi Tier\/Layer Architecture\/Design<\/p>\r\nNesse artigo, Scott Hanselmann apresenta em detalhes motiva\u00e7\u00f5es e considera\u00e7\u00f5es a respeito das camadas associadas com aplica\u00e7\u00f5es LOB\r\n<p><a class=\"botao-livro\" href=\"http:\/\/www.hanselman.com\/blog\/a-reminder-on-threemulti-tierlayer-architecturedesign-brought-to-you-by-my-late-night-frustrations\" target=\"_blank\" rel=\"noopener\">Acessar<\/a><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<div class=\"card-insight\" style=\"background-color: #f0f0f0; width: 100%; padding: 35px 30px 30px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px; box-shadow: 0px 4px 0px 0px #dddddd;\">\r\n<p style=\"font-size: 24px; font-weight:bold; line-height: 28px; font-family: Montserrat;\">Um jeito (nem t\u00e3o) antigo de fazer software LOB<\/p>\r\nAt\u00e9 bem pouco tempo, a &#8220;an\u00e1lise de sistemas&#8221; consistia em descobrir quais relat\u00f3rios e consultas um software precisaria produzir. Da\u00ed, se inferia que dados seriam necess\u00e1rios e que &#8220;cadastros&#8221; teriam que ser elaborados.<\/p>\n<hr \/>\n<p>Nesses tempos, a implementa\u00e7\u00e3o de um sistema de software come\u00e7ava com a modelagem do banco de dados, somente depois eram implementadas telas de cadastro para, finalmente, elaborar relat\u00f3rios. N\u00e3o eram incomuns ferramentas &#8220;geradoras&#8221; de telas de cadastro (como Magic, Genero e afins) e outras para elabora\u00e7\u00e3o de relat\u00f3rios (como Crystal Reports).<\/p>\n<hr \/>\n<p>Nessa &#8220;vis\u00e3o antiga&#8221;, o banco de dados \u00e9 o rei. Ali\u00e1s, seguindo essa linha, \u00e9 natural enxergar o banco como lugar ideal para implementar l\u00f3gica de neg\u00f3cio. H\u00e1 um bocado de &#8220;gente grande&#8221; que ainda pensa e desenvolve software desse jeito, procurando apenas formas de evoluir no <em>frontend <\/em>para criar &#8220;telinhas mais bonitas&#8221;.<\/p>\n<p><\/div>\n<h2>Implica\u00e7\u00f5es para o Deploy<\/h2>\n<p>Embora o estilo arquitetural em camadas preconize a independ\u00eancia de cada camada, com vistas a melhoria do <em>evolvability,<\/em> n\u00e3o \u00e9 dif\u00edcil perceber que esta &#8220;promessa&#8221; n\u00e3o se cumpre, com base na forma como ocorrem os\u00a0<em>deploys\u00a0<\/em>das aplica\u00e7\u00f5es.<\/p>\n<p>N\u00e3o raro, as camadas de apresenta\u00e7\u00e3o, neg\u00f3cios e persist\u00eancia formam um bloco \u00fanico de\u00a0<em>deploy\u00a0<\/em>com acoplamento eferente para o banco de dados, que segue gest\u00e3o independente.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1613 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_05.png\" alt=\"\" width=\"360\" height=\"297\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_05.png 740w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_05-300x247.png 300w\" sizes=\"(max-width: 360px) 100vw, 360px\" \/><\/p>\n<p>Outras vezes, a camada de apresenta\u00e7\u00e3o \u00e9 segmentada no <em>deploy <\/em>dando autonomia para atualiza\u00e7\u00f5es e implementa\u00e7\u00f5es de &#8220;perfumarias est\u00e9ticas&#8221; (reproduzindo aqui comportamento desrespeitoso e m\u00edope, frequentemente observado no mercado).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1614 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_06.png\" alt=\"\" width=\"360\" height=\"322\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_06.png 740w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/camada_06-300x268.png 300w\" sizes=\"(max-width: 360px) 100vw, 360px\" \/><\/p>\n<p>Finalmente, h\u00e1 ainda cen\u00e1rios, geralmente em aplica\u00e7\u00f5es menores, onde todas as camadas formam um \u00fanico bloco de <em>deploy.<\/em><\/p>\n<div class=\"nota-insight\">\r\n<table class=\"tabelainsight\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img loading=\"lazy\" decoding=\"async\" class=\"img-insight\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img loading=\"lazy\" decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/> Uma boa forma de &#8220;for\u00e7ar&#8221; a independ\u00eancia no <em>deploy <\/em>das camadas \u00e9 projetar que cada <em>layer <\/em>habite em uma <em>tier <\/em>separada.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<h2>Conway, outra vez!<\/h2>\n<p>As arquiteturas de 4 (as vezes 3) camadas, t\u00e3o comuns em aplica\u00e7\u00f5es <em>LOB<\/em>, s\u00e3o, tamb\u00e9m express\u00e3o da lei de Conway.<\/p>\n<div class=\"nota-alerta\">\r\n<table class=\"tabelaalerta\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img loading=\"lazy\" decoding=\"async\" class=\"img-citacao\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/ico-citacao-2.png\" alt=\"\" width=\"60\" height=\"60\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img loading=\"lazy\" decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/ico-citacao-2.png\" alt=\"\" width=\"60\" height=\"60\" \/> <\/p>\n<p><em>Qualquer empresa que projeta um sistema, inevitavelmente, produz um projeto cuja a estrutura \u00e9 uma c\u00f3pia da estrutura de comunica\u00e7\u00e3o da organiza\u00e7\u00e3o.<\/em><\/p>\n<p>\r\n<p><strong>Melvin Conway<\/strong><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<p>Na maioria das organiza\u00e7\u00f5es \u00e9 comum encontrar times de desenvolvedores especialistas em\u00a0<em>frontend\u00a0<\/em>(UI e UX),\u00a0<em>backend<\/em>, especialistas de neg\u00f3cio e DBAs. Essa &#8220;estrutura&#8221; da organiza\u00e7\u00e3o se encaixa naturalmente no modelo em camadas adotado em boa parte do mercado, se tornando assim, natural, entretanto, podendo implicar em alguns desafios para o crescimento. <strong>Quando times separados tratam de cada camada, os &#8220;limites das camadas&#8221; se convertem em pontos de &#8220;coordena\u00e7\u00e3o e sincroniza\u00e7\u00e3o&#8221; e, n\u00e3o raro, se convertem em tens\u00e3o e ofensa ao <em>lead-time.<\/em><\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1757 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/coordenacao.jpg\" alt=\"\" width=\"307\" height=\"318\" data-wp-editing=\"1\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/coordenacao.jpg 683w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/coordenacao-289x300.jpg 289w\" sizes=\"(max-width: 307px) 100vw, 307px\" \/><\/p>\n<p><strong>A alternativa, separar o c\u00f3digo nas camadas por <em>features,\u00a0<\/em>se mal conduzida leva a difus\u00e3o de responsabilidades gerando ainda mais demanda de &#8220;coordena\u00e7\u00e3o e sincroniza\u00e7\u00e3o&#8221;.<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1758 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/coordenacao_2.jpg\" alt=\"\" width=\"206\" height=\"396\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/coordenacao_2.jpg 458w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/05\/coordenacao_2-156x300.jpg 156w\" sizes=\"(max-width: 206px) 100vw, 206px\" \/><\/p>\nSistemas com arquiteturas particionadas tecnicamente, como em implementa\u00e7\u00f5es mais simples do estilo em camadas, s\u00e3o adequadas para times pequenos, com no m\u00e1ximo 20 pessoas. Em times maiores, arquiteturas precisam ser particionadas pelo dom\u00ednio para serem sustent\u00e1veis. Essa \u00e9 uma das justificativas para desenvolver arquiteturas baseadas em servi\u00e7os.\n<hr \/>\n<div class=\"card-insight\" style=\"background-color: #f0f0f0; width: 100%; padding: 35px 30px 30px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px; box-shadow: 0px 4px 0px 0px #dddddd;\">\r\n<p style=\"font-size: 24px; font-weight:bold; line-height: 28px; font-family: Montserrat;\">Two-pizzas rule<\/p>\r\n<br \/>\n<strong>Jeff Bezos, fundador da Amazon, argumentou que o n\u00famero ideal de membros em um time \u00e9 aquele onde todos possam ser alimentados com duas pizzas &#8211; geralmente, sete pessoas.<\/strong> Esse posicionamento ficou conhecido como &#8220;The two pizzas rule&#8221;.<\/p>\n<hr \/>\n<p><strong>Times pequenos apresentam menos desafios para comunica\u00e7\u00e3o, reduzindo tamb\u00e9m problemas de coordena\u00e7\u00e3o e sincroniza\u00e7\u00e3o.<\/strong> Em uma arquitetura em quatro camadas, tradicional, com um time respons\u00e1vel por cada camada, ter\u00edamos ent\u00e3o um limite razo\u00e1vel de 30 pessoas &#8211; mas geralmente esse n\u00famero seria menor, n\u00e3o mais do que 20, afinal, as &#8220;aloca\u00e7\u00f5es&#8221; na gest\u00e3o do banco, por exemplo, pelo seu alto acoplamento aferente s\u00e3o menores. No mesmo modelo em camadas, uma tentativa de separar times por contexto delimitado, sem &#8220;colapsar&#8221; o c\u00f3digo, restringe o n\u00famero de times a, no m\u00e1ximo, tr\u00eas (~20 pessoas).<br \/>\n<\/div>\n<h2>Indica\u00e7\u00f5es e contraindica\u00e7\u00f5es<\/h2>\nN\u00e3o h\u00e1 nenhum estilo arquitetural definitivamente ruim ou bom. Todos s\u00e3o mais ou menos ajustados para cada contexto de problema e \u00e9 papel do arquiteto selecionar aquele que vai atender melhor as necessidades do neg\u00f3cio, respeitando restri\u00e7\u00f5es e atingindo atributos de qualidade.\n<hr \/>\n<p>O estilo arquitetural em camadas tem\u00a0<em>fit\u00a0<\/em>perfeito para dom\u00ednios onde seja poss\u00edvel resolver problemas compondo solu\u00e7\u00f5es a partir de blocos mais primitivos. Uma\u00a0<em>camada 0,<\/em> nesse contexto, forneceria os elementos mais b\u00e1sicos que seriam combinados nas camadas superiores, de maneira similar ao que acontece com os protocolos <em>HTTP -&gt; TCP -&gt; IP<\/em>.<\/p>\n<p>O estilo em camadas, por outro lado, n\u00e3o tem\u00a0\u00a0<em>fit\u00a0<\/em>natural com aplica\u00e7\u00f5es <em>LOB<\/em> modernas. Afinal, embora suportem bem evolu\u00e7\u00f5es tecnol\u00f3gicas, sofrem para acomodar adapta\u00e7\u00f5es necess\u00e1rias para o neg\u00f3cio. Tendo em vista que qualquer mudan\u00e7a de neg\u00f3cio desencadeia, potencialmente, mudan\u00e7as em todas as camadas, aponta eveleado\u00a0<em>changing coupling\u00a0<\/em>comprometendo o\u00a0<em>evolvability.<\/em><\/p>\n<h2>Para cada jornada, as ferramentas certas<\/h2>\nN\u00e3o h\u00e1 problema na maioria dos sistemas serem projetados utilizando arquiteturas baseadas em camadas. O que seria problema \u00e9 essa ser a escolha padr\u00e3o por desconhecimento de outras alternativas.\n<hr \/>\nUtilizar \u201ccamadas\u201d \u00e9 um \u201ccome\u00e7o seguro\u201d quando arquitetos ainda est\u00e3o incertos quanto a qual seria o padr\u00e3o arquitetural adequado, mas algum c\u00f3digo precisa ser iniciado. Entretanto, para garantir que a migra\u00e7\u00e3o seja poss\u00edvel, \u00e9 importante manter as camadas \u201cfechadas\u201d pelo m\u00e1ximo de tempo poss\u00edvel.\n<hr \/>\n<h2>\/\/ TODO<\/h2>\n<p>Antes de avan\u00e7ar para o pr\u00f3ximo cap\u00edtulo, recomendo algumas reflex\u00f5es:<\/p>\n<ul>\n<li>Voc\u00ea j\u00e1 lidou, ou est\u00e1 lidando, com arquiteturas \u201cviciadas\u201d pela implementa\u00e7\u00e3o do\u00a0<em>sinkhole anti-pattern<\/em>.<\/li>\n<li>Voc\u00ea j\u00e1 lidou com arquiteturas baseadas em camadas \u201cex\u00f3ticas\u201d em LOB? Como elas eram?<\/li>\n<li>Voc\u00ea enfrenta problemas de performance em sua aplica\u00e7\u00e3o decorrentes de decis\u00f5es de manter todas as camadas fechadas?<\/li>\n<\/ul>\n","protected":false},"featured_media":3831,"parent":0,"comment_status":"open","ping_status":"closed","template":"","url":[72],"sessoes":[59],"apendices":[],"capitulos":[28],"class_list":["post-1633","volume-1","type-volume-1","status-publish","has-post-thumbnail","hentry","url-permanente","sessoes-secao-3","capitulos-capitulo-3-1"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Cap 3.1 Projetando software em camadas - Manual do Arquiteto de Software<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Cap 3.1 Projetando software em camadas - Manual do Arquiteto de Software\" \/>\n<meta property=\"og:description\" content=\"Abstrair os os componentes de um sistema em camadas \u00e9 algo comum e, at\u00e9 certo ponto, inevit\u00e1vel. Identificamos rapidamente partes dos sistemas com &#8220;externalidade maior&#8221;, como em interfaces com usu\u00e1rios ou integra\u00e7\u00f5es. Com menos externalidade, temos as partes contendo a &#8220;intelig\u00eancia e persist\u00eancia&#8221; da solu\u00e7\u00e3o. Dessa &#8220;recorr\u00eancia&#8221;, provavelmente, emerge a popularidade do estilo arquitetural baseado [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/\" \/>\n<meta property=\"og:site_name\" content=\"Manual do Arquiteto de Software\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/facebook.com\/eximiaco\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-12T21:14:31+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/3.1.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"600\" \/>\n\t<meta property=\"og:image:height\" content=\"338\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@eximiaco\" \/>\n<meta name=\"twitter:label1\" content=\"Est. tempo de leitura\" \/>\n\t<meta name=\"twitter:data1\" content=\"13 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/\",\"name\":\"Cap 3.1 Projetando software em camadas - Manual do Arquiteto de Software\",\"isPartOf\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/3.1.jpg\",\"datePublished\":\"2021-05-09T11:13:41+00:00\",\"dateModified\":\"2024-01-12T21:14:31+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/#primaryimage\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/3.1.jpg\",\"contentUrl\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/3.1.jpg\",\"width\":600,\"height\":338},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Volume 1\",\"item\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Cap 3.1 Projetando software em camadas\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/\",\"name\":\"Manual do Arquiteto de Software\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization\",\"name\":\"EximiaCo\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg\",\"contentUrl\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg\",\"width\":150,\"height\":150,\"caption\":\"EximiaCo\"},\"image\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/facebook.com\/eximiaco\",\"https:\/\/x.com\/eximiaco\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Cap 3.1 Projetando software em camadas - Manual do Arquiteto de Software","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/","og_locale":"pt_BR","og_type":"article","og_title":"Cap 3.1 Projetando software em camadas - Manual do Arquiteto de Software","og_description":"Abstrair os os componentes de um sistema em camadas \u00e9 algo comum e, at\u00e9 certo ponto, inevit\u00e1vel. Identificamos rapidamente partes dos sistemas com &#8220;externalidade maior&#8221;, como em interfaces com usu\u00e1rios ou integra\u00e7\u00f5es. Com menos externalidade, temos as partes contendo a &#8220;intelig\u00eancia e persist\u00eancia&#8221; da solu\u00e7\u00e3o. Dessa &#8220;recorr\u00eancia&#8221;, provavelmente, emerge a popularidade do estilo arquitetural baseado [&hellip;]","og_url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/","og_site_name":"Manual do Arquiteto de Software","article_publisher":"https:\/\/facebook.com\/eximiaco","article_modified_time":"2024-01-12T21:14:31+00:00","og_image":[{"width":600,"height":338,"url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/3.1.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_site":"@eximiaco","twitter_misc":{"Est. tempo de leitura":"13 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/","name":"Cap 3.1 Projetando software em camadas - Manual do Arquiteto de Software","isPartOf":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website"},"primaryImageOfPage":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/#primaryimage"},"image":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/#primaryimage"},"thumbnailUrl":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/3.1.jpg","datePublished":"2021-05-09T11:13:41+00:00","dateModified":"2024-01-12T21:14:31+00:00","breadcrumb":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/#primaryimage","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/3.1.jpg","contentUrl":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/3.1.jpg","width":600,"height":338},{"@type":"BreadcrumbList","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/projetando-software-em-camadas\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/"},{"@type":"ListItem","position":2,"name":"Volume 1","item":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/"},{"@type":"ListItem","position":3,"name":"Cap 3.1 Projetando software em camadas"}]},{"@type":"WebSite","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/","name":"Manual do Arquiteto de Software","description":"","publisher":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization","name":"EximiaCo","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg","contentUrl":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg","width":150,"height":150,"caption":"EximiaCo"},"image":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/facebook.com\/eximiaco","https:\/\/x.com\/eximiaco"]}]}},"_links":{"self":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/volume-1\/1633","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/volume-1"}],"about":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/types\/volume-1"}],"replies":[{"embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/comments?post=1633"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/media\/3831"}],"wp:attachment":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/media?parent=1633"}],"wp:term":[{"taxonomy":"url","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/url?post=1633"},{"taxonomy":"sessoes","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/sessoes?post=1633"},{"taxonomy":"apendices","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/apendices?post=1633"},{"taxonomy":"capitulos","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/capitulos?post=1633"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}