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