Alura > Cursos de Programação > Cursos de Python > Conteúdos de Python > Primeiras aulas do curso Python: Fundamentos e Padrões de Arquitetura de Software

Python: Fundamentos e Padrões de Arquitetura de Software

Fundamentos de Arquitetura de Software - Apresentação

Apresentando o instrutor e o curso

Olá! Meu nome é Arthur e serei o instrutor neste curso de Introdução à Arquitetura de Software. Durante muito tempo, trabalhei na área de Programação e, nos últimos anos, também atuei na área de Coordenação de Projetos de Software. Ao longo da minha carreira, tive a oportunidade de ter bastante contato com o tema desta aula, que é a Arquitetura de Software.

Audiodescrição: Arthur é uma pessoa de pele branca, com cabelo preto e olhos pretos. Ele está no estúdio da Alura, que possui uma estante ao fundo com itens decorativos.

Dou as boas-vindas a este curso de Arquitetura de Software, que, apesar de ser focado em Python, fornecerá princípios aplicáveis a outras linguagens de programação também.

Introduzindo conceitos de arquitetura de software

Vamos iniciar entendendo o que é a Arquitetura de Software e qual é a sua importância. Além disso, compreenderemos como ela pode ser subdividida de acordo com o nível de atuação dentro de um sistema completo.

Após isso, vamos analisar na prática um exemplo de software que não possui uma arquitetura bem estruturada, utilizando um padrão de software informal chamado SmartView. Este software inicial, desenvolvido com essa arquitetura informal, permitirá uma melhor visualização dos problemas que a falta de um planejamento estruturado pode causar.

Evoluindo para arquiteturas mais formais

A partir desse ponto, faremos uma pequena evolução para uma arquitetura mais formal, conhecida como DocumentView. O DocumentView será mais estruturado, mas ainda apresentará alguns problemas. De maneira gradativa, veremos a justificativa para uma evolução para uma nova implementação, que seria o MVC (Model View Controller).

Ao final, após desenvolvermos também a parte do Model View Controller e analisarmos os problemas que ele resolve, entenderemos como ele funciona na prática. Também exploraremos suas possíveis limitações e as alternativas disponíveis.

Concluindo a introdução ao curso

A proposta deste curso é ser uma introdução à arquitetura de software. Portanto, não abordaremos todas as arquiteturas possíveis em profundidade, mas estudaremos aquelas que tentam minimizar as limitações de projetos não estruturados, de maneira progressiva.

Nos encontramos nas próximas aulas. Até mais!

Fundamentos de Arquitetura de Software - Arquitetura no mundo do software

Refletindo sobre o início na programação

Há quase 20 anos, quando estávamos aprendendo a programar, lembramos bem da empolgação inicial. Era fascinante aprender a nos comunicar com o computador e fazer com que ele executasse tarefas interessantes. Havia muitas coisas que gostaríamos de realizar, e descobrimos que isso era possível após aprender a programar. Inicialmente, pensávamos que tudo era possível, como se tivéssemos desbloqueado um novo mundo, onde poderíamos fazer tudo o que desejássemos, mesmo que isso demandasse muito esforço.

Com o tempo, começamos a ter contato com a programação de softwares mais complexos. Iniciamos estágios, desenvolvemos mais curiosidade pelo mundo da programação, observamos softwares já implementados, dos quais tínhamos acesso ao código, e percebemos que aqueles fundamentos eram adequados para criar softwares simples, como os que tínhamos em mente inicialmente. No entanto, ao aumentar o nível de complexidade, percebemos a necessidade de algo a mais.

Enfrentando desafios em softwares complexos

Ao trabalhar com softwares de alta complexidade, notamos que eles possuíam inúmeras funções, todas com um objetivo comum, mas cada uma executando uma parte da tarefa. No ambiente corporativo, percebemos que não bastava o software funcionar, pois os requisitos mudavam ao longo do tempo. Esses requisitos iniciais eram dinâmicos e, eventualmente, por demanda do cliente ou por mudanças no mercado, era necessário fazer alterações no software. Na época em que estávamos aprendendo, era difícil realizar essas alterações, pois não tínhamos uma divisão clara das tarefas dentro do software, tornando os requisitos dinâmicos um desafio em um código mal estruturado.

Além disso, ao trabalhar em um ambiente corporativo, percebemos a importância do trabalho colaborativo. Com softwares complexos, é quase impossível que apenas uma pessoa trabalhe neles. Para trabalhar em equipe, era necessário ter clareza no código. O código precisava ser claro, com funções bem definidas, e era importante ter uma divisão que permitisse às pessoas entenderem onde deveriam trabalhar, garantindo que as mudanças realizadas não prejudicassem partes do código não correlacionadas.

Reconhecendo a importância da testabilidade

Observamos também a necessidade de testabilidade, algo que não considerávamos muito enquanto aprendíamos. Realizávamos alguns testes espontâneos para verificar se o software funcionava conforme o esperado. No entanto, em um ambiente profissional, é necessário automatizar esses testes para garantir que o que foi testado anteriormente continue funcionando após várias alterações demandadas ao longo do tempo.

Identificando lacunas no conhecimento inicial

Recapitulando, o que sabíamos naquela época? Havíamos aprendido a programar, desenvolver código e dar comandos para o computador, mas faltava algo mais para desenvolver softwares mais complexos, que evoluíam com o tempo, eram escaláveis e nos permitiam adicionar mais funcionalidades. O que estava faltando?

Inicialmente, planejamento. Durante o período de empolgação ao aprender a programar, é comum não planejarmos adequadamente. Queremos desenvolver rapidamente e atacar a solução de maneira direta. No entanto, esse planejamento é crucial para garantir que a aplicação funcione bem a longo prazo.

Explorando a necessidade de organização e consistência

Faltava também organização. Precisávamos organizar tanto as tarefas a serem executadas quanto o próprio código. Geralmente, o código era feito em um único arquivo, com todas as funções misturadas, sem muita divisão ou estruturação, o que era outro ponto em falta. Era necessário estruturar e entender o que cada parte do código fazia.

Por fim, faltava consistência. Às vezes, desenvolvíamos de uma forma, depois de outra, dividíamos as funções do software de acordo com um critério em um momento, e depois mudávamos os critérios. Essa falta de consistência dificultava entender o que havia sido feito. Sem um padrão seguido, ficava difícil localizar o que foi implementado e onde.

Introduzindo a arquitetura de software

Como resposta a essas questões iniciais, surgiu a arquitetura de software. Mesmo antes de aprender formalmente sobre ela, pudemos observar sua existência. Os códigos desenvolvidos nas empresas em que trabalhamos e em repositórios online eram muito bem organizados, mas, naquele momento, não tínhamos as ferramentas para organizar da mesma maneira. Faltava a metodologia e o conhecimento teórico necessário para criar aquela organização e arquitetura de software.

A palavra arquitetura é correlacionada com a arquitetura tradicional, definida como a arte técnica de organizar espaços e criar ambientes para abrigar diversas atividades humanas. A arquitetura de software segue o mesmo princípio, mas no mundo do software. Em vez de organizar espaços, organiza o código. Modularizamos, separamos o código em diversas partes e determinamos como elas se comunicam entre si para que o software funcione adequadamente. Essa divisão permite saber onde está cada coisa e, em um cenário de alteração, facilita identificar o que precisa ser alterado para atender novas demandas.

Focando no curso de arquitetura de software

Em vez de criar ambientes para abrigar atividades humanas, organizamos diferentes algoritmos, classes e funções para que abriguem diversas funcionalidades. O foco deste curso é explorar a arquitetura de software. Primeiro, entender como ela é dividida, ter uma noção de como aplicá-la em nosso código e como avaliá-la e utilizá-la em nosso desenvolvimento.

Fundamentos de Arquitetura de Software - Código bom vs código sustentável

Refletindo sobre a Evolução na Programação

Lembrando do início de nossa jornada no mundo da programação, fomos descobrindo aos poucos que não bastava o código ser apenas funcional. O que queremos dizer com isso? Inicialmente, quando estávamos aprendendo a programar, acreditávamos que apenas o funcionamento do código, ou seja, ele cumprir as funções que tínhamos em mente, era suficiente para que aquele código fosse considerado bom. Mas, com o tempo, percebemos que o software era dinâmico e exigia adaptações durante seu ciclo de vida. Essas adaptações eram ocasionadas por inúmeros fatores.

Uma primeira possibilidade era uma mudança de contexto de uso. Com o passar do tempo, algumas necessidades que aquele software atendia já não faziam mais sentido no novo contexto de mundo e tecnologia. Tudo aquilo que foi desenvolvido e que funcionava bem em um primeiro momento não fazia mais sentido no presente, e o software teria que passar por adaptações.

Lidando com Mudanças e Desempenho

Outro motivo que gerava a necessidade de alteração do software eram as alterações de serviços externos. Muitas vezes, utilizávamos uma API, que é uma interface de software desenvolvida por terceiros e suscetível a alterações. Quando a API mudava, era necessário fazer adaptações no software para acompanhar essa mudança.

Também era comum a necessidade de implementação de novas funções e de execução de novas tarefas pelo software. Por fim, outra questão que gerava necessidade de adaptações era a necessidade de maior desempenho. Muitas vezes, alguns dos módulos desenvolvidos precisavam ser otimizados para executar mais rápido e fornecer uma experiência de usuário mais interessante.

Questionando a Confiabilidade da Memória

Pensando em todas essas necessidades de alteração, podemos fazer alguns questionamentos. Será que nossa memória é uma fonte confiável de informação? Será que podemos confiar que, daqui a meses ou anos, conseguiremos lembrar o que fizemos? Conseguiremos fazer as alterações necessárias, sabendo onde está cada elemento no código? A resposta que encontramos em nossa jornada foi que não dá para confiar apenas na memória. Precisamos ter uma organização do nosso código para que a atividade de manutenção seja facilitada ao longo do tempo.

Outro ponto que percebemos ao longo dessa jornada, e que fica também como um questionamento, é se as alterações que fazemos no nosso software podem afetar partes não correlatas. Ou seja, é possível que, ao fazermos uma atualização do nosso software ou uma inclusão de funcionalidade, todas as outras partes permaneçam funcionando corretamente? Essa é uma questão crítica no desenvolvimento de software. É importante que, enquanto estamos desenvolvendo, tenhamos a garantia de que o software como um todo não deixará de funcionar porque incluímos uma nova funcionalidade.

Explorando Arquiteturas de Software

Por fim, qual foi a arquitetura que usamos enquanto estávamos desenvolvendo? Nos momentos iniciais, não pensávamos em arquitetura. Mas é importante frisar que arquiteturas não estruturadas ainda são formas de arquitetura. Ou seja, mesmo quando não tínhamos noção de arquitetura, já tínhamos um planejamento em mente. Já tínhamos pensado no que o software precisava fazer e, para a implementação, pensávamos no código para que ele executasse aquela função. Se o código está funcionando, ele tem uma certa forma de arquitetura. A diferença é que essa arquitetura pode estar estruturada ou não estruturada. A intenção é que, em nosso desenvolvimento, foquemos nas arquiteturas estruturadas para que possamos obter todas as vantagens que elas podem trazer.

Assim, como dissemos inicialmente, aquela noção de que o código não deve ser só funcional pode ser resumida na frase de que o código deve ser funcional e sustentável. Ou seja, ele tem que funcionar não só no presente, mas também no futuro. Ele tem que ser sustentável. Precisamos trabalhar na estruturação de forma que a manutenção desse software e a inclusão de funcionalidades sejam possíveis no futuro também. Para avaliar nosso código e nossa arquitetura, podemos pensar em diferentes formas.

Teoria sobre Avaliação de Arquitetura

Vamos apresentar agora um pouco de teoria relacionada à avaliação de arquitetura, começando pela modularidade. A modularidade vem de módulos, que podemos entender como partes componentes do software. Em uma arquitetura bem estruturada, é interessante que o software seja dividido em partes. Mas por que dividir em partes? Primeiramente, isso facilita a identificação de onde está cada elemento do software. Por exemplo, se temos uma parte do software responsável pela interface, todas as alterações dessa parte serão feitas naquele módulo específico, facilitando o entendimento.

Essas partes do software têm uma relação entre si, sendo necessário que se comuniquem e interajam durante a execução do algoritmo para que a função final seja executada. Uma forma de medir o nível de conexão entre essas partes é pelo acoplamento. Dizemos que dois módulos são altamente acoplados quando estão muito correlacionados, dificultando o uso separado. Por outro lado, com baixo acoplamento, conseguimos utilizá-los separadamente e, às vezes, até para outras funções, facilitando o reuso de código.

Vantagens dos Critérios de Arquitetura

Utilizar esses critérios na elaboração da arquitetura traz várias vantagens. Primeiramente, permite a escalabilidade, possibilitando o desenvolvimento e a adição de novas funcionalidades por meio da agregação de módulos. Caso haja necessidade, podemos incluir funcionalidades no software simplesmente adicionando novos módulos ou separando cada módulo de maneira coesa.

Além disso, facilita a manutenção. Podemos adicionar novas funcionalidades e alterar as antigas com mais facilidade em um código modularizado, permitindo alterações apenas na parte do software que precisa ser atualizada.

Outro ponto é a testabilidade. Ao separar em módulos, conseguimos testar cada um individualmente. Por exemplo, se tivermos uma aplicação que valida um CPF no cadastro e no sistema de pagamentos, podemos modularizar a função de validação de CPF, reaproveitando o código tanto na parte de cadastro quanto na de pagamento. Mais do que isso, conseguimos testá-la isoladamente. Criamos uma interface que permite a comunicação com outros módulos do sistema, e essa interface pode ser acoplada a um módulo de teste para realizar testes automatizados.

Por fim, a reutilização do código é uma vantagem, como no exemplo do CPF, que pode ser reaproveitado em mais de um trecho do código. A clareza e organização também são beneficiadas, facilitando a localização dos elementos e favorecendo o trabalho em grupo.

Sobre o curso Python: Fundamentos e Padrões de Arquitetura de Software

O curso Python: Fundamentos e Padrões de Arquitetura de Software possui 245 minutos de vídeos, em um total de 64 atividades. Gostou? Conheça nossos outros cursos de Python em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Escolha a duração do seu plano

Conheça os Planos para Empresas