A arquitetura de software representa o blueprint de um sistema, referindo-se aos fundamentos estruturais na composição de blocos de software, sendo a disciplina responsável pela organização e comunicação dos elementos essenciais durante a construção de componentes modulares de software.
Quando construímos um software precisamos descrevê-lo seguindo um plano de execução arquitetural. Nesta etapa, será necessário detalhar como os blocos serão construídos, a forma como sua comunicação será efetuada, além de dividir as responsabilidades dos componentes entre as camadas de sua composição.
O termo blueprint possui sua origem no emprego em projetos de engenharia civil e arquitetura urbana, sendo usado para descrever padrões de design e estruturais a serem seguidos durante a execução de determinada construção.
Análogo a um plano de construção de engenharia civil, os passos arquiteturais precisam estar descritos detalhadamente, atuando como alicerces para que desta forma não tenhamos surpresas ao avançarmos para as etapas seguintes. Quanto mais segura e confiável for a base de arquitetura maiores serão as chances de sucesso. Assim, quanto mais alto estivermos na pirâmide do software, mais facilidade teremos de retroceder a decisões equivocadas.
O conjunto de componentes construídos a partir de uma base arquitetural, moldam a implementação/codificação das peças representando o estilo/padrão aplicado. Mudanças necessárias na base de arquitetura possuem alto custo de reversão, tornando pouco flexíveis e rígidas podendo inclusive comprometer o projeto.
Etapa de planejamento
A etapa de planejamento arquitetural de um software ocorre após a finalização da especificação de requisitos, precedendo a fase de design. Motivo pelo qual a etapa de arquitetura de software é conhecida como early design step. Planejar e implantar a arquitetura de um software significa representá-lo a partir de um alto nível de abstração.
Desta forma, a fase de arquitetura pode ser definida como um passo pertencente ao ciclo de vida do componente de software. A arquitetura de um sistema deve prever o funcionamento de suas operações sem apresentar quaisquer detalhes de implementação. O projeto de arquitetura de software deve contemplar atributos como eficiência, portabilidade, reusabilidade e confiabilidade.
É comum utilizarmos ADLs (architecture description language) para descrever arquiteturalmente componentes de software, podendo ser encontrada em vários formatos, como UML (Unified Modeling Language), diagramas, variando de acordo com os tipo de notação adotada. Alguns exemplos de ADLs são: ABACUS, ADML (Architecture Description Markup Language), Wright, Unicon, Rapide, SSEP (software and systems engineering productivity), AO-ADL (Aspect Oriented Architecture Description Language), AADL (Architecture Analysis and Design Language).
Um software precisa ser projetado para falhas, devendo prever os riscos adicionados a cada etapa que o compõe. Durante a fase de resolução do problema, a arquitetura de um sistema reflete a forma e estilos de comunicação que determinado componente deve adotar. Arquitetura de software trata-se do primeiro passo em direção a resolução de um problema, antes de sua implementação, mostrando como um software deverá ser construído e como deverá comportar-se.
A importância desta etapa, quando bem executada, revela as facilidades relacionadas a manutenções futuras e na adição de novas funcionalidades ao sistema. Quando um software segue um padrão arquitetural conhecido, poderá ser capaz de minimizar custos associados aos riscos inerentes a qualquer sistema, reduzindo impactos e possibilitando um gerenciamento de risco apropriado.
A presença dos trade-offs
Na área de arquitetura de software, sempre existirão os trade-offs: termo utilizado para descrever uma tomada de decisão necessária, em cima de determinadas abordagens arquiteturais competindo entre si, devendo pesar os prós e contras de cada uma, possibilitando que ao final, uma escolha bem sucedida possa ser realizada oferecendo a resolução de um problema específico em um determinado contexto.
Desta forma, quanto mais sólida for sua base de conhecimento e maior sua experiência, mais assertivo será o resultado de sua decisão. Imaginemos então, que este conjunto de conhecimentos tratam-se de uma pequena caixa de ferramentas que acompanhará cada arquiteto de software em sua jornada.
Quanto maior sua caixa, mais ferramentas você terá a seu dispor e mais rapidamente irá conseguir tomar a melhor decisão, resolvendo o impasse com maior riqueza de detalhes. Ao mesmo tempo, quanto menor sua caixa de ferramentas, mais limitadas serão suas opções, aumentando o risco em não prosperar em suas escolhas.
Naturalmente, caso a única ferramenta existente em sua caixa de ferramentas seja um martelo, obviamente você irá tratar tudo como sendo prego. Precisamos estar atentos em sempre usar a ferramenta certa para o trabalho certo e isto nem sempre está vinculado a nossa linguagem de programação favorita.
A disciplina de arquitetura de software
Quando nos deparamos com as primeiras leituras sobre a disciplina de arquitetura de software, enxergamos diversas opções junto a uma infinidade de conceitos ainda desconhecidos e inexplorados. Assim como em qualquer disciplina, precisamos de base sólida de conhecimento para entender determinados conceitos e seguirmos em frente.
A base exigida para o sucesso nas decisões de um arquiteto irá variar de acordo com a complexidade de cada assunto envolvido no contexto de cada projeto. Para se aventurar, obtendo sucesso na compreensão da disciplina será necessário esforço buscando absorver conhecimentos cada vez mais relevantes e cultivando a procura incessante pela informação.
Quanto mais absorvemos informações e evoluímos, maior será o amadurecimento de conceitos já existentes em nossa caixa de ferramentas. Sempre existirão obstáculos, porém a vontade de seguir em frente e levar a disciplina de arquitetura de software cada vez mais a sério e presente em nossas rotinas como profissionais de arquitetura nunca poderá enfraquecer-se.
O papel do arquiteto de software
Durante a etapa de definição de arquitetura de um projeto, o arquiteto deve assumir o controle do processo, implicando desde estudos de caso envolvendo soluções de mercado, identificação de trade-offs e tomadas de decisão com teor técnico. Assim, a este profissional torna-se obrigatória a detenção de uma base de conhecimento sólida para o enquadramento e composição do desenho técnico apropriado para cada cenário, dando origem à devida especificação sendo adequadamente confeccionada.
Não podemos subjugar nem menosprezar uma das etapas mais importantes e essenciais para a execução bem sucedida de um software: o estágio de planejamento de arquitetura. O principal problema, em muitas situações, refere-se a definição de postura a ser imposta pelo arquiteto de software em relação a apropriação de insumos técnicos necessários para nortear uma noção mais madura do que precisaria ser compreendido, e posteriormente seguido, no âmbito técnico, o que nem sempre acontece. Em outras palavras, ocorre falta de competência técnica para tomada de decisões cruciais.
Quando percebemos a desconexão entre o peso da responsabilidade imposta pelo estágio arquitetural de um software e a superficialidade de conhecimento dominante no profissional de arquitetura, acabamos com uma execução prática pobre, desordenada e desorganizada.
Assim, para superarmos a falta de conhecimento exigida para o desempenho pleno do papel na etapa de arquitetura e preenchermos estas lacunas evidentes, precisamos perseguir o aperfeiçoamento profissional cada vez maior em direção a tornar o trabalho dos arquitetos de software cada vez mais reconhecido dando a disciplina de arquitetura cada vez mais relevância.
A importância do entendimento de arquitetura
Ao refletirmos sobre os softwares sob um viés de responsabilidade, comunicação e tudo que cerca as camadas de arquitetura, inevitavelmente acabamos nos dando conta que as percepções referem-se a pontos de vista isolados aos olhos de quem os observa. Ao olharmos de perto será possível perceber as nuances de uma cadeia evolutiva, pretendendo sintetizar toda uma evolução tendo se passado algumas décadas.
A partir deste contexto, podemos refletir sobre os movimentos/avanços que nos trouxeram até a modernidade, permitindo-nos contemplar o estado da arte para determinados padrões que prosperaram. Constatamos, desta forma, que diversos detalhes ocorreram silenciosamente enquanto seguíamos em frente. A partir desta reflexão, compreendemos que conceitos comuns, atribuídos atualmente a alguns componentes modernos, tratam-se apenas de uma projeção do passado, carregando consigo o peso e complexidade inerentes às raízes de sua descendência.
Quando nos referimos a disciplina de arquitetura de software, precisamos dedicar esforços para entender os motivos pelos quais tais direcionadores arquiteturais existem e nos trouxeram até aqui. Conhecendo seus antecessores, precisaremos entender como e porque evoluíram, ou os motivos por terem sido ultrapassados. Até que por fim, consigamos ter uma visão clara de quais serão as próximas tendências.
Uma estratégia sólida facilitará previsões sobre o futuro destas tecnologias, quais irão se manter no jogo e quais estarão ultrapassadas nos anos seguintes. Observar tendências nos permite realizar comparações mais assertivas, refletir sobre determinadas escolhas, oferecendo maior facilidade em resolver os trade-offs que surgirão.
Aprofundamento superficial dos conceitos
Embora, em muitos casos, a falta de dedicação necessária visando atingir a plenitude técnica no campo arquitetural, apresentar-se como uma realidade latente, parte deste cenário pode ser explicado adiante as facilidades presentes em padrões e estilos de arquitetura prontos para uso no mercado. Neste caso, a utilização de padrões mais rudimentares empregados em cenários mais complexos coloca em risco o sucesso do projeto de software.
Na maioria das vezes, a etapa de definição de arquitetura, e o entendimento da sua importância acaba sendo subjugado. É bastante comum vermos desenvolvedores e arquitetos seguirem receitas de bolo sem mesmo interessar-se em conhecer os detalhes para justificarem sua utilização.
Ainda assim, será sempre importante termos o papel de um arquiteto, independente de sua experiência, responsável pela execução prática desta etapa. Este papel, deve participar ativamente, não somente da etapa de concepção do software como da evolução do seu ciclo de vida.
Quando responsabilizamos alguém por determinada atividade, provemos um dono para aquele processo ou etapa, garantindo maior qualidade na execução do que foi desenhado no momento da concepção técnica de arquitetura.
A importância da etapa de arquitetura pode ser observada na execução de um software bem sucedido. Componentes de software quando pensados de forma modular desde sua concepção tornam sua comunicação e divisão de responsabilidades mais inteligente e flexível.
Quando idealizados em uma etapa de arquitetura apropriada, os componentes possuem maior sofisticação e elegância, apresentando visivelmente maior qualidade tanto durante seu ciclo de vida quanto facilitando sua manutenção.
Conseguimos observar a qualidade sendo refletida na redução de custos para manutenção posterior as entregas, incluindo a inserção de novos componentes, integrando-se ao ecossistema geral da arquitetura adotada.
Estilos arquiteturais (Architectural Styles)
Estilos arquiteturais referem-se a uma terminologia que caracteriza, através aparência estética, componentes de software cujo o design seja notável e identificável a partir de uma visão do nível mais alto de abstração. Quando definimos o estilo arquitetural de nosso software estamos interessados em prever como as camadas e módulos irão comunicar-se, identificando e isolando suas responsabilidades. Existem diferentes tipos de estilos arquiteturais, podendo ainda serem combinados produzindo estilos híbridos adicionais.
Dentre os principais estilos podemos citar cinco grandes grupos: structure (layered, pipes and filters, component-based), shared memory (role-based, blackboard, database-centric), messaging styles (Implicit invocation, asynchronous messaging, publish-subscribe), adaptive systems (microkernel style, reflection, domain-specific language) e distributed systems (service-oriented, peer to peer style, object request broker, cloud computing), deployment (client-server, n-tier).
Estilos arquiteturais são considerados soluções visando resolver certas classes de problemas os quais compartilham um conjunto de atributos semelhantes agnósticos a tecnologia. Não existe um único estilo capaz de resolver todos os problemas, pois cada sistema possui particularidades.
Como exemplo, alguns sistemas direcionam esforços a nível de segurança enquanto outros preferem focar na capacidade de ser real-time. Desta forma, estilos arquiteturais sempre irão beneficiar determinados atributos em favor de outros de acordo com os propósitos iniciais definidos.
Estilos arquiteturais são responsáveis por prover conectores, interfaces e regras de combinação entre eles, promovendo o reuso e o design de particionamento entre componentes compactos.
Conceitualmente, estilos e padrões arquiteturais diferem-se dependendo de qual nível estamos descrevendo o software. Uma vez referindo-se a coisas distintas em diferentes níveis de abstração, estilos procuram oferecer uma visão periférica em torno do problema a ser resolvido. Por outro lado, padrões descrevem o processo de como determinado objeto deve ser construído, na esfera de solução concreta para alguns problemas comuns em contextos comuns, responsáveis por balancear o custo e o benefício sob o resultado obtido.
A necessidade de entendê-los possibilitará adotar com maior assertividade a melhor escolha para cada projeto. Existem diversas abordagens para resolvermos problemas de software, sendo de responsabilidade do arquiteto a tomada de decisão com relação aos trade-offs de cada proposta arquitetural.
A mais importante característica, não somente em arquitetura de software, mas no campo de engenharia de software, trata-se da abstração empregada pelos padrões que a sustentam. Cada estilo arquitetural define uma família de sistemas, semanticamente coerentes, contendo um conjunto padrão de componentes integrados a topologia de cada layout.
Dentro de um estilo existem princípios e formas para definição dos componentes, conectores e interação compondo uma espécie de vocabulário de comunicação para uma solução. Juntamente com um conjunto de restrições impostas, os estilos refletem na maneira em como são combinadas e distribuídas as responsabilidades entre os componentes de software.
Existem diversos estilos arquiteturais na indústria, podendo ser categorizados individualmente: communication, deployment, domain, structure.
Arquitetura de software oferece uma representação do sistema permitindo entender o comportamento de seus elementos. Possibilitando uma definição, tanto na esfera estrutural como de interação entre os componentes computacionais. O mais importante aspecto relacionado a arquitetura trata-se da presença de Software Patterns (padrões de software), guiando atividades de design e apresentando regras de como e quando deveríamos criar nossos blocos de software.
O ciclo de desenvolvimento de um software apresentará maior qualidade tanto na experiência quanto no suporte adequado quando atrelado a raízes arquiteturais sólidas.
Embora a importância do design para arquiteturas de software seja reconhecida, ainda continua sendo vista como uma etapa complexa e com pouca orientação. Estilos arquiteturais são uma manifestação das decisões de design representando o significado desta abstração, utilizado para impor uma separação conceitual adequada e segura.
Estilos e padrões arquiteturais diferem-se estruturalmente através do seu escopo de aplicabilidade. Digamos, um estilo poderia ter um significado mais amplo: “relacionado à maneira de fazermos algo”, enquanto qualquer outro conjunto de padrões, sejam arquiteturais ou de design, referem-se a uma esfera mais decorativa dos blocos internos de um componente de software.
Conhecendo o escopo de determinado conceito a ser aplicado, além de sua definição, será possível entendermos com facilidade seu objetivo. Desta forma, o foco de utilização de um padrão, junto ao seu seu nível de granularidade, direcionam sua aplicabilidade. Portanto, hierarquicamente teremos os estilos arquiteturais ocupando o nível mais alto de abstração para composição do design dos componentes de software.
Distinguirmos os níveis de granularidade existentes trata-se de um passo importante para a compreensão da hierarquia de utilização de cada padrão.
Padrões Arquiteturais (Architectural Patterns)
Na disciplina de engenharia de software, padrões arquiteturais (architectural patterns) possuem o propósito de serem soluções gerais e reutilizáveis para componentes a nível de aplicação para problemas recorrentes dentro de um determinado contexto. Portanto, sendo uma solução recorrente para um problema recorrente.
Padrões arquiteturais possuem natureza conceitual, sendo aplicados com flexibilidade variando seu nível de granularidade em seu escopo de aplicação. A diferença entre estilos e padrões arquiteturais ocorre no escopo do problema a ser resolvido.
Nada impede de termos a combinação de diversos padrões arquiteturais dentro de uma mesma solução de software, permitindo-nos enxergar como os módulos de um determinado componente de software interagem. Quando entendemos a forma como as peças se encaixam entre as camadas de um sistema compreendemos com maior transparência a fluência na comunicação entre os níveis de responsabilidade arquitetural.
Em alguns casos, elementos arquiteturais compõem maneiras de resolver problemas particulares, restritos especificamente a um pequeno contexto onde foi concebido.
Certas estratégias podem ser definidas e documentadas como padrões de arquitetura, podendo ser disseminadas para uso pontual em determinados subsistemas, promovendo o reaproveitamento. Percebemos desta forma a evidente diferença entre um padrão de arquitetura (architectural pattern) e um estilo arquitetural (architectural style). Um padrão, simplesmente focando na resolução de problemas específicos a determinado contexto, não transcendendo suas regras de responsabilidade e comunicação através do restante do sistema.
Por outro lado, as regras de um estilo arquitetural recaem sobre uma condensação de necessidades, descrevendo a responsabilidade entre os componentes em alto nível, focando na solução apresentada como um todo (top-down).
Descrevemos informalmente que um padrão arquitetural detém seu foco em um problema específico, propondo a resolução de suas divergências somente na combinação do emprego de técnicas isoladas.
O conjunto de padrões e estilos de arquitetura são atrelados a uma representação fixa, empregados a determinados sistemas ou contextos, convidando-nos a refletir sobre camadas ou componentes estruturados unitariamente. Individualmente, temos padrões arquiteturais opondo-se aos estilos, que por sua vez concentram-se em uma esfera mais abstrata do design de arquitetura dos objetos.
Muitos profissionais de software (TI) confundem estilos e padrões de arquitetura, acreditando serem a mesma coisa e atacando problemas semelhantes.
Ao compreendermos as diferenças ao empregar formas e métodos de construção, não somente entre estilos e padrões arquiteturais mas adicionalmente entre e design patterns (padrões de design), teremos maior facilidade ao descermos aos níveis mais técnicos de da aplicação (detalhes de implementação). Assim, será possível perceber com maior clareza suas responsabilidades conceitualmente distintas nas camadas superiores.
Alguns detalhes de interações em tempo de execução destes componentes não estão relacionados a aspectos técnicos de sua arquitetura e sim de aplicação.
A arquitetura em alto nível, descrita a partir de um determinado ecossistema, pode conter um ou mais estilos arquiteturais. Ao mesmo tempo, um estilo arquitetural pode se valer do uso de diversos padrões arquiteturais, presentes em uma mesma solução, dado sua aplicabilidade em contextos específicos.
No contexto de arquitetura, independente do nível de isolamento, sempre buscamos o desacoplamento de responsabilidades com o objetivo de promovermos a reutilização dos componentes. Estudar seus pontos fortes e fracos facilita aplicarmos múltiplos padrões combinados em um único sistema visando otimizá-lo.
Padrões arquiteturais são soluções comprovadas evidenciando a existência de problemas recorrentes. A arquitetura de um sistema trata-se do entendimento compartilhado da forma como os componentes estão divididos, entregando uma visão geral de como os componentes interagem através de suas interfaces preestabelecidas.
Exemplos de estilos e padrões arquiteturais
Uma única aplicação pode conter diversos estilos de arquitetura, ao mesmo tempo em que cada estilo pode fazer uso de vários padrões arquiteturais. Alguns dos principais estilos arquiteturais são:
- Client-Server
- Component-based
- Layered
- Publish-subscribe
- Plug-ins
- Pipes and Filters
- Service-Oriented Architecture (SOA)
- REpresentational State Transfer (REST)
- Domain Driven Design
- Microservices
Quanto aos padrões arquiteturais, os mais conhecidos são:
- Model-View-Controller (MVC)
- Microkernel
- Three-tier
- Event-driven (EDA)
- Message Broker
- CQRS (Command and Query Responsibility Segregation)
Considerações finais
Todo o software precisa de um design arquitetural para representar sua essência, descrevendo em alto nível seu comportamento. De modo geral, o design de arquitetura é definido como uma coleção de componentes de hardware e software estabelecendo suas interfaces de comunicação com o mundo externo. Através de seu comportamento e aparência, cada componente expressa a categoria de estilo arquitetural a qual pertence, possuindo características notáveis e identificáveis.
Estilos arquiteturais não resolvem problemas, representando apenas maneiras recorrentes de arquitetura com um propósito geral a ser seguido.
A adoção de estratégias de alto nível precisa ser efetivada, contendo aspectos particulares de relacionamento e comunicação entre os principais componentes de um produto. Nosso software estará maduro somente após ter passado com sucesso pela esteira de arquitetura, assim quanto mais rigorosa for esta etapa maior qualidade será agregada ao produto final.
Desta forma, a fase de arquitetura bem executada facilitará a manutenção posterior dos elementos, possibilitará uma visão ampla de seu funcionamento como um todo, além de garantir maior facilidade na tomada de decisões futuras. Por fim, vale reforçar a importância da etapa de arquitetura e do papel do arquiteto de software, guiando o projeto em direção ao sucesso.