Uma das dúvidas mais prementes em desenvolvimento é entender a diferença entre Design e Arquitetura. E muita gente vai lhe explicar como eles são diferentes. Como design tem mais que ver com código e coisas como os Princípios SOLID e que arquitetura tem mais que ver com os atributos do sistema como Segurança e Escalabilidade.

Isso não é mentira, mas pode ser redutor. É como explicar a diferença entre cara e coroa sem dizer que ambas fazem parte da mesma moeda. Esses artigos são bons para nos aprofundarmos nos detalhes de cada conceito, mas falta algo que os una. Veremos neste artigo como Design e Arquitetura estão relacionados e não são duas disciplinas desconexas.

A primeira coisa a entender é que tudo é Design e que, consequentemente, Arquitetura é Design.

Tudo é Design

Construir um software é antes de mais uma atividade intelectual que tem apenas que ver com tomar decisões. Não é realmente sobre escrever código. Isso é como, não o quê .Todas as decisões que você toma enquanto constrói um software são decisões de Design. Desde qual linguagem usar, qual código escrever, quais entidades usar até como distribuir o sistema em que OS o sistema vai rodar ou que cor o botão de login vai ter.

Nada é deixado ao acaso, Tudo são decisões. O conjunto de todas essas decisões são o Design. Simples assim.

Design Incidente vs Design Emergente

Existem duas principais formas de como um desenvolvedor toma as decisões.

Algumas decisões são tomadas conscientemente e com um propósito especifico. O conjunto destas decisões é chamado de Design Incidente. Por exemplo, quando você escolhe a plataforma Java porque quer que o sistema rode em qualquer OS, e escolhe Kotlin para programar porque é a linguagem com que sua equipe tem mais familiaridade você está tomando especifica e conscientemente a sua decisão.

Algumas outras decisões simplesmente decorrem das decisões incidentes ou são forçadas por alguma circunstância. Por exemplo, se o cliente quiser um sistema web, a sua decisão de usar um servidor HTTP não é realmente sua escolha. É algo que nasce da circunstância de um sistema web ser baseado em HTTP.

Como o design emergente depende das circunstâncias e as circunstâncias mudam ao longo do projeto, novas decisões têm que ser tomadas para adaptar o trabalho que já foi feito às novas necessidades. Este acumulo de decisões não controladas e não previstas leva, se não houver cuidado, a um design ininteligível. Design emergente também pode ser considerado design ad hoc, ou seja, aquela se produz o resultado esperado, mas que não sabemos por quê.

Atualmente muitos desenvolvedores acreditam que o design emergente é algo bom e que Agile é, não apenas, adequado a ele, mas como uma necessidade. Isto advém da confusão entre Design Incidente e Big Design Up Front (BDUF). Ha uma diferença entre todo o design ser consciente e com propósito – design incidente – e todas as features terem que ser desenhadas nos primeiros dias do projeto – BDUF. Ter algumas decisões conscientes e especificas de propósito no inicio é sempre necessário. Por isso, muitos advogam o conceito de Some Design Up Front ou Little Design Up Front, na tentativa de deixar claro que no inicio do projeto algumas decisões são sim obrigatoriamente incidentes. Como por exemplo, qual linguagem usar. Não é algo que você pode decidir depois. O mesmo é válido para a plataforma, por exemplo.

Decisões Reversíveis vs Decisões Irreversíveis

As decisões de design se separam em decisões reversíveis (soft) e irreversíveis (hard).

Em inglês ouvimos falar de hard decisions (decisões irreversíveis) e soft decisions (decisões irreversíveis)

Decisões reversíveis são todas aquelas que você pode decidir diferente depois. Por exemplo, você criou uma classe factory, mas depois decidiu que não precisava e passou a usar o construtor diretamente. Tudo bem.Mas, algumas decisões são irreversíveis. Não quero dizer totalmente irreversíveis, já que nenhuma decisão em software é completa e totalmente irreversível. Chamamos assim porque o custo, o tempo ou ambos, seriam tão proibitivos que realmente a probabilidade de haver a mudança é muito próxima de zero. Para todos os efeitos práticos consideramos irreversível aquilo que é muito custoso e difícil (hard). Por exemplo, se escolher C#.NET para desenvolver e depois de 3 anos compreende que deveria ter usado Scala em Java, não é possível reaproveitar o código de um jeito fácil. No fim, ou continua com C# ou vai ter que escrever o software de novo em Scala.

Isto nos leva ao conceito de Arquitetura

Arquitetura é Design

Arquitetura é o (sub)conjunto das decisões de Design que são irreversíveis.

Então acaba sendo que em arquitetura você terá de decidir sobre plataformas, linguagens, segurança, escalabilidade, performance … tudo coisas que não serão simples nem baratas incluir no software depois. Você pode mudar de uma arquitetura monolítica para uma de micro-serviços? sim, claro, mas terá um custo. Não é algo estritamente irreversível, mas é muito custoso e difícil (hard).

É pela razão da arquitetura lidar com decisões mais permanentes que ela ganha importância e é comparada à arquitetura de casas (de onde tomamos emprestado o nome). Depois que você constrói uma casa é complicado mudar o banheiro ou a cozinha de lugar. Claro, não é impossível, mas provavelmente é mais barato e simples comprar outra casa.

Estas “coisas fixas” da arquitetura de casas são realmente muito importantes e formam a base do livro A Pattern Language: Towns, Buildings, Construction (Christopher Alexander et all) de 1977 onde os autores falam sobre conceitos e dicas que elas consideram repetidas ou referencias absolutas, a que eles chamaram de Pattern (Padrão).

Esta foi a base para o celebre livro do Gang of Four : Design Patterns: Elements of Reusable Object-Oriented Software (Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides) de 1994. O livro absorve a ideia de que sempre que estão em causa certas forças, com certos constrangimentos, e se queremos seguir os Princípios de Design iremos percorrer um mesmo raciocínio e portanto tomar a mesma decisão.

O conceito de Padrão (Pattern)

Padrão é, em software, um conjunto de decisões que têm por base um raciocínio bem estabelecido em princípios de Design com resultados comprovados.

De uma forma muito simplista podemos dizer que Padrões de Design (Design Patterns) são decisões pré-prontas ao mesmo tempo que são relações conhecidas entre decisões. Uso o termo Padrões de Design em vez de Padrões de Projeto porque acho que não é uma boa tradução, fora que se acharmos coisas repetidas nos projetos como vamos chamar ? E sim, existem padrões em estabelecer e conduzir projetos como o Principio da Mínima Surpresa, o Principio de Pareto, o Principio de Dilbert, a Lei de Brooks e tantos outros… Bom, acho que afinal esses não se chamam padrões, chamam-se princípios e leis. Impõe mais respeito.

Se temos Padrões de Design, teremos Padrões de Arquitetura, já que Arquitetura é um subconjunto do Design. Normalmente os desenvolveres fazem grande distinção entre os dois tipos. É realmente importante destingir já que um padrão de arquitetura tem que com algo que vai ficar permanentemente dentro do software e será muito difícil de mudar. Exemplos são destes padrões são Separação em Camadas, Model-View-Controller, Pipe-Filter, Producer-Consumer e aquilo que redundantemente chamados de “arquiteturas” como Client-Servidor, MicroServiços, Event-Bus, Peer-to-Peer, entre outros.

Já os Padrões de Design que não são de Arquitetura, são mais relacionados ao código como Factory, Singleton, Bridge, Strategy, Command, Value Object, Repository, Entity entre outros.

Entenda que, na prática todos são padrões de design e que todos influenciam o código que você escreve. Não poderia ser de outra forma, já que software é código e todas as decisões que você toma são sobre como escrever esse código.

Código Sem Design

Estritamente falando não é possível tem um código sem design, porque não é possível ter um código sem ter tomado decisões, e o design nada mais é que o conjunto de decisões. Mas da mesma forma que falamos que uma sala, ou uma mobília, tem design ou não, também falamos que de um código ter design ou não.

Quando falamos que algo tem design, não nos referimos que decisões foram tomadas, mas sim que elas foram tomadas de uma forma consciente, causal e principalmente, correlacionada. Ou seja, não foram decisões aleatórias ou à toa. Existiu um raciocínio e uma apreço pelas consequências. As decisões têm um fio condutor, embora nem sempre seja óbvio qual é, sentimos que ele está lá.

Em software código com design é isso, um código que foi escrito com intenção e com conhecimento das implicações e consequências que ele tem no todo. Ele pode ser considerado monótono ou excêntrico conforme a moda, mas será com ou sem design considerando a intenção.

Isto nos leva de volta ao conceito de Design Incidente. Todo o código tem design, mas o melhor código tem Design Incidente. Nem todo o código pode ter design incidente e temos que viver com uma parte de Design Emergente de vez em quando, mas quanto mais Design Emergente seu código tem, pior. Mais difícil de mudar ele será, por que por definição você não entende ou controla essa parte do design. É um design espontâneo difícil de controlar.

Usar Design Incidente não é simples. Não brota das pedras como o Emergente. Design Incidente requer estudo e constante evolução. O design Incidente de ontem não mais vale hoje porque aprendemos certas coisas no meio tempo. É preciso ter muito cuidado com o que decide. Especialmente se a decisão é reversível ou não. Um código com design é aquele que minimiza as decisões e aos mesmo tempo maximiza as decisões reversíveis. Um código com design toma poucas decisões e todas são reversíveis. Na prática, não há como só tomar decisões reversíveis. Como vimos, a escolha da linguagem, por exemplo, é um decisão irreversível que é impossível não fazer.

Como vimos todo o código tem design, mas há diferentes tipos de combinações de design que podem existir no seu código:

ReversívelIrreversível
IncidenteÓtimo
É aqui que você quer estar. Tomando decisões conscientes que podem ser revertidas com pouco esforço. Mas isto exige conhecimento, treino e estudo.
Menos bom
Não tem como escapar de tomar um decisão irreversível de vez em quando. Você quer minimizar este tipo de decisões. Tornar decisões Irreversíveis em Reversíveis deve ser seu principal objetivo como desenvolvedor.
EmergenteNada bom
Tomar uma decisão emergente pode ser bem enganador e estranho de reverter depois, mas se a decisão é Reversível existe a oportunidade de a tornar Incidente e Reversível depois. Não é aqui onde você quer estar no seu processo de decisão, mas poderia ser pior.
Péssimo
Uma decisão emergente e irreversível é pior que pode acontecer. Porque é irreversível não será possível mudar, mesmo quando descobrir que havia uma solução melhor e sendo emergente você nem entende bem a razão que está comandando aquela decisões ou está tão amarrado pelas circunstâncias que não pode decidir de outra forma.

Como pode ver é verdadeiramente importante tomar Decisões Reversíveis de forma Incidente. É isto que chamamos intuitivamente de “Bom design”. Um bom design leva a um código de fácil manutenção e fácil alteração quando as circunstâncias mudam. Isto não significa que vão existir poucas classes. Significa que você vais entender todas as classes. O número de classes não é métrica da qualidade do seu design.

Se você se achar em um dos outros quadrantes o que pode ser feito para voltar ao primeiro ? Vejamos.

  • Design Irreversível e Incidente – você pode aplicar técnicas como padrões de arquitetura e design para tornas suas decisões irreversíveis em reversíveis. O objetivo é isolar a parte irreversível dentro de uma parte plugável do design. Bridge e Strategy sãos bons para isto. Aplicar padrões não toma muito do seu tempo e é uma boa forma de garantir resiliência às mudanças que virão. Em contrapartida não é qualquer um que consegue analisar o código e conseguir isto. Provavelmente irá precisar de um desenvolvedor mais sênior na sua equipe.
  • Design Emergente e Reversível – talvez este seja o mais fácil de lidar. Torne o design Incidente entendendo a razão dos constrangimentos e das consequências. Aplicar Padrões de Design pode ajudar a isolar o código que corresponde com o que é realmente emergente e o que é incidente. Compreender mais os requisitos e a possibilidades de solução podem tirar você deste quadrante. Um bom analisador de requisitos e pessoas treinadas tanto em design como arquitetura podem ajudar.
  • Design Emergente e Irreversível – este é o mais difícil. Tente ao máximo compreender por que é uma decisão irreversível. Talvez adicionando mais um camada ou alguma biblioteca você pode tornar a decisão mais reversível. Por exemplo, se você tiver que usar um certo banco de dados é bom garantir que consegue mudar para outro com pouco esforço. A tecnologias escolhida para a conexão vai ditar a irreversibilidade da decisão, então escolha bem. Nem todas as decisões neste quadrante podem ser movidas para outro quadrante. Tente entender quais não podem e seguir em frente. Por exemplo, a escolha da linguagem pode ser uma decisão emergente – quando é imposta pelo cliente , ou a equipe só sabe uma linguagem – e sempre é irreversível. De novo, um bom analisador de requisitos e pessoas treinadas tanto em design como arquitetura podem ajudar.

O Arquiteto

Se tomamos emprestado o nome Arquitetura para nos referirmos ao design irreversível (hard) , também tomamos emprestado o conceito de Arquiteto. Não há muito tempo ser arquiteto era um escalão da carreira de um programador. Em algumas empresas ainda é. Isto leva rapidamente ao anti-padrão conhecido como Ivory Tower. Hoje em dia se abomina essa palavra e esse cargo (deveria, pelo menos). O arquiteto de software não é um cargo, é um conjunto de skills que uma pessoa tem. Se arquitetura é um conjunto de decisões irreversíveis, o arquiteto é aquele desenvolvedor que consegue contornar essas decisões com melhor custo/beneficio para o projeto. O estudo e experiência vão acumulando, e perante um problema essa pessoa já sabe como decidir. O que vemos hoje em dia é as empresas chegarem à conclusão de que o cargo de Arquiteto é um anti-padrão e com isso jogam foram o conceito e os skills em si, assumindo que qualquer conjunto de desenvolvedores num squad pode realizar o mesmo. Ou seja, assumem que X juniors + Y seniors = 1 Arquiteto. Nunca foi, não vai ser agora, por mágica.

É vital ter uma pessoa com conhecimentos de arquitetura durante o processo de desenvolvimento do software. Especialmente no principio, mas não apenas no principio. É necessário que essas pessoa participe continuamente de forma a garantir que futuras decisões são compatíveis com decisões anteriores. Como vimos, tomar decisões é um processo continuo em desenvolvimento de software. É o próprio desenvolvimento de software. E muitas dessas decisões serão irreversíveis e/ou emergentes se decididas por pessoas despreparadas. É do interesse de todos que as decisões sejam tomadas por pessoas preparadas. E aqui não se trata de apenas ter senioridade, mas de realmente ter capacidade. Não é todo o mundo, nem todo o senior, que é um bom arquiteto, mesmo quando a pessoas se intitula Arquiteto. Especialmente se a pessoa se intitula Arquiteto.

Como o processo de desenvolvimento é um continuo de tomadas de decisões todos temos que ser designers de software, e como algumas dessas decisões serão irreversíveis, todos somos um pouco arquitetos. Mas sermos designers e arquitetos, não significa que somos bons designers e arquitetos. Tomar boas decisões, e ser um bom Designer e um bom Arquiteto, requer estudo e experiência.

De Médio , de Músico (, de Designer) e de Louco, todos temos um pouco. Mas se você quer ser um desenvolvedor profissional, precisa ter bem mais que um pouco de Designer. E para isso precisa estudar. Estudar padrões sejam de design ou de arquitetura é um bom principio. Além disso há que estudar os designs de outros sistemas e frameworks e praticar. Praticar bastante. Lembre-se que em desenvolvimento:

Tudo é Design.

Um comentário para “Design e Arquitetura”

  1. […] vimos antes, “uma arquitetura” é o nome que damos a um conjunto de decisões especificas que […]

Comente

Scroll to Top