Modularização de Software
Tags: softwareengineering, architecture, go
Published: 2023-12-19 14:33:15

## Definições Relacionadas
**- Modularização:** Processo de dividir um sistema de software em módulos. Esses módulos são projetados para realizar tarefas específicas e interagir entre si de forma bem definida.
**- Módulo:** Unidade de código independente e reutilizável com uma tarefa específica. Agrupamento de funcionalidades relacionadas a um componente de um software.
**- Software Modular:** Abordagem de design que organiza programas em módulos interconectados para facilitar manutenção e reutilização.
**- Submódulo:** Parte específica de um módulo maior, focada em uma função específica.
**- Subsitema:** Entidade autônoma que faz parte de um sistema maior, composta por módulos interconectados para desempenhar uma função específica.


## Algumas Influências na história da Modularização
**- Desenvolvimento de Software Estruturado:** De 1960 e 1970, Edsger Dijkstra, Niklaus Wirth e outros, enfatizaram a necessidade de dividir programas em estruturas lógicas e bem definidas.
**- Programação Modular:** Niklaus Wirth, contribuiu para o conceito de programação modular com linguagens como Pascal. Ele enfatizou a importância de dividir um programa em módulos independentes e coesos.
**- Desenvolvimento de Linguagens de Programação:** Linguagens, como C e posteriormente C++, facilitaram a criação de módulos e bibliotecas reutilizáveis, promovendo a modularização.
**- Engenharia de Software:** Década de 1960, trouxe abordagens sistemáticas para o desenvolvimento de software, incluindo a ênfase na modularização para facilitar o projeto, teste e manutenção.
**- Padrões de Projeto:** Década de 1990, Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides, forneceram soluções recorrentes para problemas de design de software, muitas vezes envolvendo princípios de modularização.
**- Desenvolvimento Ágil:** Promove a modularização, incentivando equipes a criar software de forma iterativa e incremental, com ênfase em módulos funcionais.


## Passos para a modularização 
**1 - Compreensão dos requisitos do software:** Analisar detalhadamente os requisitos do software para entender completamente as funcionalidades necessárias
**2 - Divisão do problema em partes:** Identificar as principais funcionalidades e divida o problema em partes menores e mais gerenciáveis
**3 - Identificação das funcionalidades em cada parte:** Listar as funcionalidades específicas que cada parte do sistema deve oferecer. Isso ajudará a definir claramente o escopo de cada módulo.
**4 - Separação das partes em Pacotes (ou Namespaces):** Agrupar as funcionalidades relacionadas em pacotes ou namespaces. Isso facilita a organização e a compreensão do código.
**5 - Conexão entre os módulos:** Definir interfaces claras para a comunicação entre os módulos. Especificações de entrada e saída, bem como protocolos de comunicação, devem ser claramente definidos.
**6 - Implementação de cada módulo:** Desenvolver cada módulo de forma independente, focando na implementação das funcionalidades identificadas.
**7 - Testes dos módulos:** Realizar testes para garantir que cada módulo funcione conforme o esperado. Isso ajuda a identificar e corrigir erros em um estágio inicial.
**8 - Integração e Testes do Sistema:** Integrar os módulos para formar o sistema completo e fazer testes de integração para garantir que todos os componentes funcionem de forma coesa.
**9 - Documentação dos módulos:** Documentar a função de cada módulo, a arquitectura, o fluxo de funcionamento, suas interfaces, dependências e qualquer informação relevante. 
**10 - Refactoração e Melhoria contínua:** Fazer os ajustes no código fonte à medida que os requisitos e o software mudarem.


## Acoplamento e Coesão

### Acoplamento
**- Definição:** Grau de dependência entre os módulos de um sistema. Ele indica a medida em que um módulo conhece e depende de outros.
**- Baixo Acoplamento:** Implica mais modular, flexível e fácil de manter. As mudanças em um módulo têm menos impacto nos outros.
**- Alto Acoplamento:** Os módulos estão fortemente interconectados. Isso pode levar a dificuldades na manutenção, já que as alterações em um módulo podem afetar vários outros.

### Coesão
**- Definição:** Medida em que os elementos dentro de um módulo estão relacionados entre si. Indica o quão bem as responsabilidades de um módulo estão agrupadas.
**- Alta Coesão:** O módulo tem responsabilidades relacionadas e está focado em realizar uma única tarefa. Isso facilita a compreensão, manutenção e reutilização do código.
**- Baixa Coesão:** As responsabilidades estão menos relacionadas, o que pode tornar o código mais difícil de entender e manter.

### Relação entre Acoplamento e Coesão
Acoplamento e coesão possuem uma relação inversa. Em resumo, à medida que o acoplamento aumenta, a coesão tende a diminuir. 
Isso acontece porque um alto acoplamento indica uma forte conexão entre os componentes, dificultando a identificação de um propósito comum. 
No design de sistemas, o objetivo é minimizar o acoplamento e maximizar a coesão para criar estruturas mais simples, compreensíveis e de fácil manutenção.


## Vantagens da Modularização
**- Reusabilidade do Código:** Permite que módulos específicos sejam reaproveitados em diferentes partes de um sistema ou em projetos diferentes.
**- Manutenção Simplificada:** Facilita a identificação e correção de problemas, uma vez que as mudanças podem ser realizadas em módulos específicos sem afetar o sistema como um todo.
**- Facilidade de Teste:** Possibilita a realização de testes unitários mais eficientes, pois é possível isolar e testar cada módulo separadamente, garantindo uma cobertura mais abrangente.
**- Desenvolvimento Paralelo entre as Equipes:** Diferentes equipes podem trabalhar de forma independente em módulos específicos, acelerando o desenvolvimento do sistema como um todo.
**- Escalabilidade:** Permite que o sistema cresça de maneira mais eficiente, adicionando ou modificando módulos conforme necessário, sem impactar negativamente outras partes do sistema.


## Desafios da Modularização
**- Design Inicial Complexo:** É necessário muito esforço na fase de design para definir interfaces claras entre os módulos e garantir uma estrutura modular eficaz.
**- Gestão de Dependências:** O controle e gerenciamento das dependências entre os módulos podem se tornar complexos, especialmente em sistemas grandes.
**- Coordenação entre Módulos:** Garantir a integração eficiente e a comunicação adequada entre os módulos pode ser desafiador, exigindo uma coordenação cuidadosa.
**- Overhead de Comunicação:** A comunicação entre módulos pode resultar em um overhead significativo, especialmente se não for otimizada, afetando o desempenho do sistema.
**- Atualização Sincronizada:** Actualizar ou modificar um módulo pode exigir a coordenação com outros módulos dependentes, o que pode complicar o processo de atualização.
**- Complexidade de Gerenciamento:** A gestão de um grande número de módulos e suas interações pode se tornar complexa, exigindo ferramentas eficientes e processos bem definidos.

## Recomendações
Actualmente os arquitectos, engenheiros e desenvolvedores de software, estão engajados com arquiecturas modernas, frequentemente adoptadas por Big Techs tais como: Microservices, Clean Architecture, Hexagonal Architecture, Event-Drivel, CQRS e outras.
Recomenda-se que os profissionais de software adquiram um conhecimento aprofundado dos princípios de modularização de software antes de experimentarem essas novas aquitecturas, a fim de evitar erros fundamentais e risco de overengeneering.  A absorção do conceito de módulos pode ser combinado de forma sinérgica com essas arquitecturas, resultando num software escalável e reutilizável.
A compreensão do conceito de modularização de software é essencial para qualquer profissional de sofware. Trata-se de um conhecimento atemporal que resistiu ao teste do tempo e permanece indispensável. A prática da modularização, ao longo dos anos, demonstrou sua eficácia inabalável e continuará sendo um elemento crucial na engenharia de software.

## Exemplo
Neste exemplo vamos criar um software modular baseado em **ERP (Enterprise Resource Planning)** utilizando a linguagem de programação **Go** e o SGBD **PostgreSQL**. 
O sistema será composto por quatro módulos principais: Autenticação, Configurações, Recursos Humanos e Clientes.

**Código fonte:** https://github.com/ortizdavid/golang-modular-software