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 é 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.
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.
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?
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?
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).
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).