Arquitetura de Software, qual é a importância de uma boa arquitetura ?

Arquitetura de software, qual é a importância ?           

 

            Quem já ouviu falar de arquitetura de software, os nome MVC, N-Tier e MVVM não são nada desconhecidos. No entanto, há quem tenha dificuldades em desenhar um software usando camadas(sim, todos estes padrões de projeto que eu falei são padrões por camadas).

              O objetivo deste artigo é explicar-vos a minha experiência com arquitetura de software e as dificuldades que eu tive, antes de perceber para que servia.

               No início, eu escrevia código corrido. Escrevia tudo às cambalhotas e as pessoas que trabalharam comigo(universidade) não entendiam o meu código. Estavam sempre com aquelas perguntas:
"André, o que faz a linha 3 ?";

"Não percebo o que isto faz. Não te consigo ajudar".

             No entanto havia outro problema. Os meus colegas que trabalharam comigo também entendiam pouco de arquitetura de software e baseavam-se em código da Internet. Sim, o código funcionava, mas está bem estruturado ? Está de forma a que o outro consiga ler ? Os professores, graças a Deus, que avaliam a qualidade de código. Uma pessoa que sabe fazer refactoring de código é uma pessoa que depois na apresentação do software ao professor ou à equipa, vai saber explicar o código.

  Como começar a entender arquitetura de software?

     A primeira coisa que acho que todos têm de entender é algoritmia. Sem isso, nunca na vida vão conseguir refatorar um código. Quando eu ouço falar de código limpo, a primeira coisa que devemos pensar é olhar para o nosso código e perceber o que eu posso por numa função. Isto é o básico da algoritmia. Quando vocês aprendem algoritmia aprendem que procedimentos e funções servem para modular o código de forma a que consiga-se se ler melhor. Depois há aquelas modas do DRY, do Clean Code. Sim, é tudo muito bonito, mas sem entender o que significa o que está por trás dessas normas não adianta aplicar Clean Code ou DRY. Dessas normas o que está por trás é conceitos básicos que todos os programadores devem saber e que são coisas óbvias. Por exemplo, escrever variaveis que todos possam entender.

    Um exemplo em Javascript:

 

 

 

        Este código é simples e toda a gente sabe o quê que isto faz. Agora imaginem, um projeto com 3000 linhas de código com nomes de variaveis assim. A primeira pergunta que vocês fazem a quem criou o código é esta:
"O que é o h ?"

        Agora isto que está aqui já se percebe melhor:



 

         O h afinal era uma saudação. Isto não vos é óbvio e básico ?

         Ao vocês entenderem isto, vocês não precisam sequer de entender o que é o Clean Code, o que é o DRY. Não entendam isto mal. Não sou contra o DRY e o Clean Code. São princípios que são bons para toda a gente, no entanto o que eles falam são coisas que são muito óbvias.

          Arquitetura de Software, muita gente associa à Object Oriented Programming. Mas não é só isso. Podem aplicar em qualquer linguagem de programação até mesmo o C só que talvez ia demorar um pouco mais de tempo a fazer.

         Que arquitura de software devo usar ? Existe alguma melhor ?

            Esta pergunta não tem uma resposta correta. É algo que passa por uma decisão de equipa de desenvolvimento. Se vamos usar N-tier, se vamos usar MVC, MVVM, Clean Architecture, Hexagonal Architecture isso é tudo uma decisão que a equipa de desenvolvimento deve avaliar. Primeiro é preciso ver se a equipa tem tempo para desenvolver. Se a equipa tem tempo para desenvolver, então talvez seja uma boa decisão usar uma Clean Architecture. A vantagem deste design pattern é que dá para trocar por exemplo uma base de dados por outra sem quebrar o funcionamento da aplicação. 

             Uma coisa que é importante perceber é que muita gente diz que usar uma estrutura de pastas qualquer já é um determinado padrão. Não necessariamente.

             Eu posso chamar models, à minha pasta domain. Isso não quer dizer que deixe de ser Clean Architecture ou NTier ou MVC.

 Refactoring de código

           A Clean Architecture por exemplo, por ser uma arquitetura que dá para substituir uma coisa por outra é importante ter o código bem estruturado. O problema é que abstrai muito e às vezes se torna difícil de implementar. Por isso é que às vezes as empresas têm falta de tempo para fazer a manutenção por quererem tudo para ontem e o código e a arquitetura acaba por falhar. Por isso ser uma decisão de equipa.
             Eu por exemplo, a minha maneira de pensar é primeiro colocar tudo a funcionar direito e depois refatorar o código. Uma coisa que eu não gosto é de refatorar o código dos meus colegas de equipa. Acho que isso é algo que tem de ser conversado com o autor do código se posso refatorar o código dele. Sim existe exercicios de refactoring e é bom pegar nesses exercicios e fazer. Assim aprendemos a fazer refactoring. No entanto, pegar em código de colegas e refatorar acho que não é correto. Se o colega pedir, é uma coisa e tem de ser feita em conjunto com esse colega.
                 
            Este refactoring mais tarde vai permitir a criação de testes unitários e de integração de forma mais fácil. Por exemplo, o mecanismo de autenticação de um utilizador. 
              Em Javascript, podemos o usar JWT, o bcrypt para criar um sistema de login e autenticação para o express. Normalmente o que a gente faz é criar um middleware para fazer a autenticação.
               Numa fase inicial, se seguirem a minha lógica de fazer as coisas, tem sentido, no entanto depois da funcionalidade estar feita vamos analisar o código e dizemos


"Isto não funciona com o Hapi. Que estranho".

Porquê ?
Porque nos acoplamos ao Express.
Será possível por exemplo desacoplar do express e usar o mesmo sistema no Hapi ?
Sim!! Vou vos mostrar um exemplo de código que eu estou a desenvolver a nível pessoal:


Este middleware está acoplado ao express ou seja se vocês usarem o Hapi não vai funcionar. Como é que eu posso mudar este código de forma a funcionar tanto com Hapi como Express, ou o NestJS ?

Reparem que neste código o que está a ser analisado é o token. O token vem do cabeçalho HTTP de autorização. Não seria incrível eu passar já direto na função o token vindo do header e fazer as operações necessárias ?

Então só tinhamos de retirar o req e o res e colocar o token:
 

 
 
 
Assim, já consigo usar esta função no Hapi sem depender do express. O controlador do express é que vai tratar o erro e dizer se é 401 ou se é 403 ou o que seja.
Portanto desta forma é possível abstrair a lógica do express da autenticação. Depois vocês só têm de chamar este serviço no express e  não precisam de usar middlewares que dependam do express. Porquê ? No primeiro código, estou a dar detalhes de implementação. Ou seja estou a dizer que vou usar a API do Express e vou retornar um JSON. O segundo código não sabe de onde vem token só sabe que se for um token inválido que vai disparar um erro e não sabe sequer se esse erro é um json um XML ou um HTML ou seja o que for. Só sabe que vai disparar um erro e o Express e o Hapi que tratem do erro da forma como quiserem.
E se amanhã eu trocar o express pelo NestJS vou ter esta função sempre disponível. Isto chama-se refactoring de código.

Se eu amanhã quiser fazer um teste unitário a este serviço de autenticação, eu consigo facilmente.
 

Vantagem da arquitetura de software

        A vantagem de uma boa arquitetura é reduzir os custos de desenvolvimento e dificuldade de manutenção. 

 

Conclusão 

        Para concluir, é preciso ver a questão do tempo que se tem para desenvolver o software. Se não há tempo, então usa-se uma arquitetura mais simples. Se tivermos podemos nos aventurar um pouco numa arquitetura que o custo de manutenção é mais barata no entanto se não há tempo, o projeto tem de ser desenvolvido.