quinta-feira, 7 de maio de 2020

Arquitetura de Software

Para entendermos a necessidade de se arquitetar um software, alguns conceitos devem ser apresentados, bem como os desafios com os quais um profissional desta área deve lidar.
Historicamente, os fracassos de projetos de softwares são significativos. De acordo com Hastie e Wojewoda (2015), o Chaos Report da Gartner de 2015 mostra que apenas 29% dos projetos foram bem sucedidos, 52% chegaram ao final ainda necessitando de ajustes e 19% falharam. Os fatores críticos de sucesso estão relacionados à natureza complexa e intangível do software.
O software é visto pelas áreas de negócios como algo flexível e adaptável, porém sabemos que um software não arquitetado pode dificultar sua manutenção, escalabilidade e reúso.
Desta forma, desenvolver soluções arquitetadas é uma prática que tornará nosso trabalho, a longo prazo, menos reativo e estressante.

Mas o que é arquitetura de software?

Uma arquitetura registra informações sobre como os elementos de software se relacionam uns com os outros, ocultando ou explicitando elementos do software que devem ou não existir em diferentes níveis de abstração.

Aqueles que possuem vivência na área de desenvolvimento de software sabem que, muitas vezes, uma mudança ou um novo requisito tem impacto estrutural e demanda grande esforço de desenvolvimento e, se realizado sem planejamento, desencadeia efeitos colaterais em todo o software.

Modelagem de aplicações de softwares

Como você já deve ter estudado, um aplicativo de software possui um ciclo de vida. Ao longo deste ciclo, muitas mudanças são realizadas e geram impactos no código escrito nas primeiras versões do software.
O software é afetado por um fenômeno de degradação que impacta sua confiabilidade, estrutura e sua consistência. Sua documentação fica desatualizada, dificultando sua manutenção e tornando-a onerosa.
Sabemos que um processo de desenvolvimento definido que favoreça a obtenção e a validação dos requisitos pode minimizar esses impactos, porém o fato de o software ser visto como algo flexível torna a definição de uma arquitetura um elemento fundamental para o desenvolvimento de software em larga escala.
Se você já desenvolveu algum software ou até mesmo uma planilha eletrônica com várias referências a fórmulas em diferentes arquivos, já percebeu que existe um limite para a capacidade humana para compreender, ao longo do tempo, aquilo que foi produzido, tornando esta uma atividade complexa.
O software possui uma natureza complexa crescente, seja pelo número de linhas de código ou pela sua intangibilidade. Logo, a criação de modelos torna-se indispensável para compreensão do que está sendo desenvolvido.
O uso de modelos apoia o entendimento e a definição da arquitetura do software, assim como a identificação das regiões críticas que podem sofrer degradação ao longo do tempo.
No processo de criação de modelos, muitos problemas podem ser antecipados e decisões são tomadas a fim de minimizar seu impacto ao longo do tempo.

IMPORTANTE
Blaha e Rumbaugh (2006, p. 17) definem modelo como uma abstração de algo que facilita seu entendimento antes de construí-lo. Abstração é um processo mental básico que permite lidar com a complexidade, omitindo detalhes não essenciais.

No processo de produção do software, modelos são criados para descrever a estrutura e o comportamento de um software para posterior implementação. Estas descrições de modelos guiam a construção e mantêm registros das decisões tomadas na sua concepção.
Para os criadores da Unified Modeling Language (UML), Booch, Rumbaugh e Jacobson, nenhum modelo único é suficiente. Qualquer sistema não trivial será mais bem investigado por meio de um conjunto de modelos quase independentes com vários pontos de vista.
Um ou mais modelos podem servir de inspiração para dar origem a uma arquitetura que sustente as necessidades do que está sendo modelado.
Cada área de conhecimento adota tipos específicos de modelos. Na engenharia de software contemporânea, segundo Booch, Rumbaugh e Jacobson (2006), adota-se uma perspectiva orientada a objetos, onde a UML é empregada para visualização, especificação, construção e documentação de artefatos que orientam o desenvolvimento do software.
Para entender a importância de controlar esta complexidade, vamos analisar no próximo tópico o trabalho de Brooks (1987), que faz uma classificação dos aspectos que estão sob nosso controle e aqueles que fogem dele, impactando o cronograma, o custo e a equipe de projeto do software.




Tarefas acidentais e essenciais

Independentemente do processo de desenvolvimento de software adotado, um conjunto de tarefas é organizado e realizado. Tais tarefas são classificadas por Brooks (1987) como tarefas acidentais e essenciais:
  • As tarefas acidentais estão relacionadas à implementação do software e as principais preocupações estão ligadas à sintaxe das linguagens, aos limites de hardware, aos ambientes e ferramentas de desenvolvimento e a demais aspectos técnicos. Estes aspectos são facilmente superados com treinamentos, leituras ou por meio de consulta a um profissional mais experiente.
  • As tarefas essenciais estão relacionadas ao processo mental de criação de um conjunto de conceitos que se interligam.
Tanto as tarefas acidentais quanto as essenciais criam barreiras para o desenvolvimento de software, porém grande parte das barreiras acidentais foi transposta na última década e as principais falhas de projetos estão relacionadas às atividades essenciais que criam barreiras que dificilmente são domináveis.
De forma análoga, e neste contexto, pode-se comparar o processo de desenvolvimento de software ao processo de criação de um texto, em que as tarefas acidentais estão relacionadas ao domínio de uma ferramenta de edição de textos, a sintaxe e a semântica da língua. Tais tarefas podem criar barreiras para a produção do texto, mas serão superadas com algum nível de estudo ou apoio de terceiros, porém não garantem que o texto escrito atenderá critérios de qualidade.
Logo, o domínio de tarefas acidentais não garante a qualidade do que está sendo produzido. A qualidade será definida pela forma peculiar de criação e organização das ideias atuando sobre a construção mental e essencial que será descritos de forma textual.

Aspectos essenciais na produção de software

Brooks (1987) elenca quatro aspectos essenciais que impactam na produção do software. São eles: complexidade, conformidade, flexibilidade e intangibilidade. Estes aspectos são descritos a seguir.

Complexidade

Entidades de software possuem uma natureza complexa. Assim, aumentar sua escala não é meramente repetir os mesmos elementos em tamanho maior. É necessário um aumento do número de elementos diferentes, amplificando a complexidade do todo de forma não linear.
Queremos dizer que existe uma grande diferença entre fazer um software com poucas linhas de código e desenvolver um software com um número maior de requisitos.
Para um software mais robusto, não basta aumentar as linhas de código. É necessário incluir elementos de software para facilitar o entendimento das linhas já produzidas, a manutenção, a inclusão de novas funcionalidades, o aumento da equipe, a padronização e a inclusão de interfaces, entre outras demandas exigidas por um software de maior escala.

Imagine um artesão trabalhando na produção de um vaso de barro. Você, de passagem em turismo pelo local, adorou aquele vaso. Em função disso, solicitou ao artesão que produzisse 1.000 unidades, pois presentearia seus familiares e venderia o restante dos vasos na sua cidade de origem.


REFLITA

O processo e as ferramentas de produção adotados pelo artesão seriam suficientes para atender sua encomenda? Bastaria apenas aumentar em quantidade a matéria-prima do artesão? Contratar mais artesões garantiria a beleza do vaso apreciada por você? O processo para produzir uma unidade é o mesmo para produzir 1.000 unidades?

Acredito que chegará facilmente à conclusão que novos elementos deverão ser inseridos no processo de produção do vaso. Talvez o uso de formas para garantir o padrão, a contratação de novos artesões, uma sequência ordenada de tarefas, a criação de modelos que serão submetidos a testes, entre outras ações.


AGORA, REFLITA: 

O que diferencia a produção de um software de 1.000 linhas de código com um de 15.000 linhas? Será só a quantidade de linhas?

Softwares com 1.000 linhas de código, no pior caso, podem ser refeitos gastando apenas mais alguns dias de trabalho; entretanto, reescrever um sistema mais complexo levaria meses ou anos. Portanto, cuidar da arquitetura no início reduz os problemas futuros.

Da complexidade, vem a dificuldade de entender e se comunicar com os membros da equipe de desenvolvimento, levando à deficiência do produto, que aumenta os custos e afeta o cronograma e a confiabilidade. Da complexidade da estrutura, surge também a dificuldade de entender o comportamento e ampliar os programas sem criar efeitos colaterais, tornando árduo o gerenciamento destes problemas.
Provavelmente, muitos dos programadores já passaram por situações em que não conseguiram ou demoraram para entender um código, seja ele gerado por terceiros ou até mesmo um código próprio.
Segundo Brooks (1987), a complexidade do código é crescente e existe um limite que o cérebro humano consegue gerenciar, impactando na quantidade de novas linhas de código que podem ser acrescentadas a um programa ao longo do tempo.

À medida que o software é implementado, ou seja, linhas de código são inseridas, sua complexidade cresce e afeta a produtividade ao longo do tempo.

Aspectos essenciais na produção de software

Conformidade e flexibilidade

Outras áreas do conhecimento também lidam com a complexidade crescente, mas como o software não está suscetível às leis naturais, é visto como algo flexível e de fácil adequação, ao menos se comparado à Física e outras ciências.
Brooks (1997) afirma que, em decorrência da sua complexidade, a versão inicial de um software muitas vezes não atende aos requisitos na sua plenitude, necessitando de constantes mudanças, de tal modo que todo software de sucesso acaba sendo modificado. Assim, um sistema de software deve ser concebido para mudar.
Caso você já atue na área de desenvolvimento de software, deve ter percebido que a mudança dos requisitos é algo constante. Isso não significa que as mudanças são correções de erros, mas podem decorrer de novas funcionalidades para atender às necessidades de negócios. Vale dizer que a TI deve impulsionar os negócios e não ser um gargalo para novas oportunidades. Logo, precisamos desenvolver softwares nos quais uma mudança não afete toda a estrutura já desenvolvida.
Nosso código deve “aceitar” mudanças com certa flexibilidade, comunicar claramente suas responsabilidades, facilitar a manutenção e proporcionar o reúso. Esse é o grande desafio!

Intangibilidade

Softwares são intangíveis, portanto, é difícil criar uma representação visual objetiva e comum para eles. Ao tentar diagramar uma estrutura de software, descobre-se que ela não é apenas um, mas sim vários diagramas superpostos uns aos outros, sem hierarquias ou relações diretas entre seus elementos, forçando cortes que eliminam conexões nas diferentes vistas do modelo.
Para Brooks (1987), esses cortes prejudicam não só o processo
de projeto do software, mas também a comunicação entre os
membros da equipe.
A UML é uma poderosa ferramenta capaz de tangibilizar as descrições de implementação do arquiteto de software.
Um arquiteto de software deve apoiar-se em descrições de modelos para comunicar suas decisões de implementação. Um diagrama UML, analogamente, pode ser comparado com uma planta hidráulica ou elétrica que um engenheiro civil ou eletricista utiliza para tangibilizar um modelo mental e comunicar seu projeto.
Portanto, a descrição de modelos de software apoiados em diagramas é uma ferramenta essencial para um arquiteto de software e um dos elementos que o difere do programador.
Antes de prosseguir, convém recordar o que é o paradigma orientado a objetos (OO) e alguns de seus conceitos mais importantes.


UML: um breve histórico

A UML surgiu da união de três metodologias de modelagem: o método do americano Grady Booch, o método OMT (Object Modeling Technique), do sueco Ivar Jacobson, e o método OOSE (Object-oriented Software Engineering) do americano James Rumbaugh. Estas eram, até meados da década de 1990, as três metodologias de modelagem orientada a objeto mais populares. A união dessas tecnologias contou com o apoio da Rational Software, que incentivou e financiou a união das três metodologias. O esforço inicial do projeto começou com a união do método de Booch com o de Jacobson, o que resultou no lançamento do método unificado no final de 1995. Logo em seguida, Rumbaugh juntou-se a Booch e Jacobson na Rational Software, e seu método OOSE começou a ser incorporado à nova metodologia. O trabalho de Booch, Jacobson e Rumbaugh, conhecidos popularmente como “os três amigos”, resultou no lançamento, em 1996, da primeira versão da UML propriamente dita.
Assim que a primeira versão foi lançada, diversas grandes empresas atuantes na área de software passaram a contribuir com o projeto, fornecendo sugestões para melhorar e ampliar a linguagem. Finalmente, a UML foi adotada pela OMG (Object Management Group), em 1997, como a linguagem padrão de modelagem.
Fonte: Guedes (2014, p. 15-16).

Nenhum comentário:

Postar um comentário