quarta-feira, 14 de janeiro de 2009

A Arquitectura Aplicacional — Factores de Sobrevivência

[Este é o terceiro artigo da série “A Arquitectura Aplicacional” I) Introdução II) Análise de Características]

No último artigo abordei algumas das características que caracterizam (esta é que não sabiam) uma arquitectura aplicacional. Não foi feita uma análise exaustiva, pelo que, com certeza, muitas características importantes terão não sido referidas. Como exemplo, não foi referida, explicitamente, a vulgar característica «expansibilidade» [reconheço que a palavra não me soa perfeita; mas não consegui encontrar as palavras «escalabilidade» ou «escalável», num dicionário de português (de Portugal), mas apenas: escala, escalar, escalada, escalamento, escalagem e escalador. Por isso, acabei por preferir os tradicionais termos «expansibilidade» e «expansível», utilizados aqui à semelhança de em “slot de expansão”], que descreve a aptidão de uma arquitectura para poder crescer, em termos de carga suportada, ou na sua distribuição geográfica.

Neste artigo, exploro algumas características que, julgo, são hoje subestimadas no desenho de sistemas e arquitecturas aplicacionais.

É comum dar-se muita importância a cada um dos componentes ou módulos de um sistema e menosprezar a importância que tem o que os une, os liga e o que partilham e trocam uns com os outros.

A modularidade — as caixas

Estamos na época da modularidade, e de pouco mais. Também já não é mau, reconheço que podia ser pior. É-nos suficiente. Satisfaz-nos. Decora as soluções com traços de inteligência e complexidade, o que fica sempre bem. Enche o olho de quem compra. O deslumbramento é tanto que nem se quer saber o que é que está dentro dos módulos, as caixas, pretas. São quartos escuros, geralmente com tanta luz quanta inspiração e cuidado.

Na pior das hipóteses, se se descobrir que um módulo não presta: deita-se este fora e troca-se por outro. É higiénico, não se toca em mais nada (tal como se faz hoje em dia com as placas de circuito impresso — nem vale a pena tentar descobrir qual o transístor que está queimado).

Relação com a mediocridade

A modularidade é uma característica imprescindível de qualquer sistema e arquitectura. Só não deve é ser utilizada para esconder o lixo debaixo do tapete. Como qualquer arma, esta pode ser usada bem ou mal. Para flexibilizar, separar, proteger e arrumar, ou para esconder a confusão, o desmazelo e a ignorância.

Eis algumas máximas, todas elas válidas em devido contexto, mas que, evocadas de cor, facilmente conduzem a um uso medíocre da modularidade:

“Depois, se houver tempo, faz-se melhor…”

“A qualquer altura se substitui…”

“Faz-se iterativamente e acrescenta-se faseada e oportunamente”

“É uma questão de compromisso entre isto e aquilo…”

“O óptimo é inimigo do bom…”

“Não sejamos mais papistas que o Páapa”.

Notem os seguintes, igualmente válidos, dizeres:

“Raramente há tempo e oportunidade para melhorar o que já está (mais ou menos) feito”

“O que nasce torto (ou incompleto) tarde ou nunca se endireita (ou completa)”

“Quando não há vontade, qualquer razão serve…”

“O bom também é inimigo do óptimo”

“Com o mal dos outros posso eu bem”

“A qualidade compensa, gasta-se agora, ganha-se depois”

“Para hábil executor é tão mais fácil fazer bem do que mal”

A flexibilidade — as ligações

A modularidade é tanto acerca de caixas como de ligações.

Deparados com um monólito de 1000 linhas [porque não em C#, já que este é um blog ligado a tecnologias Microsoft], feito por um qualquer colega insano [que devia ser mandado para o Campo Pequeno e…], a necessidade imperativa de reposição da ordem que invade qualquer programador que se preze, debate-se imediatamente com o seguinte: para separar, há que ligar a seguir. É essa a razão por que mentes preguiçosas, sob a pressão dos prazos, se ficam pelo monólito: “É mais seguro, fica tudo juntinho e não se perde”.

De que são feitas as ligações? De um fio condutor e dos electrões. Isto na electricidade, é claro, porque no caso das aplicações informáticas, é, surpreendentemente, a mesma coisa. Façamos F = “fio condutor” e E = “electrão”. Entre funções de um programa: F = “variável” e E = “um inteiro”, entre uma página web e o seu servidor: F = “canal tcp/ip, protocolo http” e E = “conteúdo do body da mensagem http”, e por aí adiante.

A flexibilidade de um sistema deve-se à flexibilidade das ligações entre os seus módulos.

Uma ligação não é flexível apenas por existir (existo logo sou flexível?). Uma função não está ligada de forma flexível às funções suas chamadoras apenas por ter muitos parâmetros de entrada (e, eventualmente, vários de saída). Não é tanto a quantidade de ligações que traz a flexibilidade, mas antes a qualidade do que as atravessa.

A flexibilidade de um conjunto de ligações é função do número de fins que estas podem produzir.

Eis um exemplo da “vida real”. O corpo humano, assim como muitos outros organismos vivos, é um sistema extraordinariamente flexível. A sua flexibilidade deve-se em grande medida à flexibilidade do seu (sub-)sistema de ligações. Os vasos sanguíneos — o canal condutor, F — ligam todos os pontos do corpo; pelo meio, atravessam barreiras físicas, como as articulações entre os membros, sem prejudicar a sua mobilidade; penetram fundo nos seus órgãos internos. O sangue — o líquido portador — viaja nos vasos sanguíneos levando consigo alimentos, glóbulos e demais agentes de toda a espécie — E.

A reter:

Todos os sistemas bem sucedidos, que sobrevivem, perduram e evoluem, são flexíveis. Têm como suporte às ligações entre as suas partes um (sub-)sistema de ligações flexível.

As coisas

O domínio do que é comunicado, do que viaja através dos canais de comunicação, é, na mais geral das hipóteses, todo o conhecimento (“the sky is the limit”), cujo elemento abstracto se denomina de «coisa». Pode ser uma mensagem, um “objecto”, um número inteiro, uma entidade de negócio, enfim, qualquer «coisa».

Quanto mais tipos diferentes de «coisas» puderem passar por uma ligação, maior será a sua flexibilidade. Maior será, também, a dificuldade de lidar com “tanta «coisa»”. Por isso, a utilização eficiente das ligações, passa por descobrir, para o problema subjacente aos módulos ligados, qual é o menor conjunto de «coisas» que o descreve.

Actualmente, quando se desenham sistemas e arquitecturas, nmho, não se tira partido de um eficiente desenho do modelo de entidades de negócio. É comum que cada módulo ou camada de um sistema tenha o seu bem diferente modelo de entidades, do mesmo negócio. Não são apenas diferentes vistas parciais de um mesmo modelo, de acordo com as necessidades de cada um. São antes diferentes, contraditórias, e igualmente infiéis representações de um mesmo modelo de negócio, que todos mal conhecem.

A utilização de um modelo de dados comum em todo um sistema é o maior potenciador da sua eficiência, a todos os níveis, e da simplicidade conseguida nas suas ligações [reveja-se o corpo humano].

No próximo artigo, abordarei alguns sentidos desafios do desenho de um tal modelo de dados. Até lá. Não resistam. Pensem nisto.

Sem comentários: