No último post falamos sobre Acoplamento e Coesão, que são medidas que devemos sempre levar em grande consideração no projeto de qualquer software.
E nada melhor que entender a teoria aplicada, ou seja, vê-la na prática. Vamos começar a refletir sobre isso.
Neste post vamos falar sobre Acoplamento e Coesão em Módulos e Funcionalidades.
Acompanhe esta série de posts, pois falaremos ainda sobre estas duas medidas aplicadas em vários outros modelos/artefatos do processo de produção de software.
Qualquer software – seja um aplicativo comercial, um sistema de gestão, um website, um aplicativo mobile ou até mesmo um jogo – é composto, basicamente, de Módulos e Funcionalidades.
Um software é um todo. Módulos são conjuntos dentro deste todo. Funcionalidades são elementos deste conjunto.
Qualquer projeto deve começar na parte “mais alta” do escopo, ou seja, no nível de abstração mais macro. E este nível sempre é o do Módulo. Após a definição dos módulos, é necessário definir suas Funcionalidades.
/* Um dos maiores erros dos Analistas de Sistemas é começar a entender um problema do nível mais detalhado para depois tentar compreendê-lo num nível menos detalhado. Ou seja, ater-se ao micro, sem antes entender o macro. Geralmente quando isso acontece o Analista pensa soluções que na maioria das vezes não serão aderentes ao todo, ou ao “resto”, gerando impacto negativo no restante do escopo do software. Porém, depois da solução estar aplicada, na maioria das vezes não dá mais para refatorar. */
Como surgiu a prática de modularizar o software?
Quando falamos que algo é “modular”, ou “modularizado”, podemos entender que este algo é organizado em “pedaços”, ou “partes”, para que se tenha benefícios em termos de organização, compreensão, manutenção, reuso etc.
Antigamente, quando os primeiros programas foram produzidos, o conceito aplicado à época era o do projeto ou aplicações monolíticas, onde todo o escopo (tanto funcional quanto técnico) era “embutido” num único programa.
Este conceito aplicava-se a praticamente tudo em termos de TI, não apenas ao software. Os servidores, estações de trabalho, impressoras, dispositivos de rede etc. eram mais monolíticos do que modulares.
Eu penso que isso era natural, não era caso de omissão. Era a forma como os profissionais pensavam ser melhor.
Mas isso gerava como efeito softwares altamente acoplados, pois do ponto de vista arquitetural, eram sistemas “tudo em um”. E em relação a coesão não havia como ter o devido cuidado, pois as responsabilidades se misturavam ao extremo em softwares feitos de tal forma.
Ainda hoje, em alguns contextos da produção de software, há quem defenda o uso do modelo monolítico (em aplicativos mobile por exemplo). Em alguns casos talvez se aplique, pois modularizar em excesso também não é boa prática. Mas não vou me estender muito nesse raciocínio, não é o foco deste post.
Quando este modelo começou a apresentar problemas os profissionais da Computação começaram a pensar em separar os sistemas em “pedaços”, quebrando cada sistema em pedaços menores, facilitando assim os trabalhos de projeto e manutenção.
/* A ideia de separar um problema em partes menores (preferencialmente indivisíveis), visando simplificar o problema e viabilizar um total entendimento sobre cada uma de suas partes, tratando cada uma como uma parte de um todo, não é nova. René Descartes nos trouxe isso, em seu Método, que foi/é a base para o pensamento científico e de qualquer Engenharia da nossa humanidade. */
E isso evoluiu primeiro no contexto mais técnico.
Nos Mainframes (computadores de grande porte [tanto de armazenamento como de processamento]) os programas foram sendo “quebrados” em Rotinas, Sub-Rotinas e Jobs. Isso começou a ser viável quando o Assembly já não era mais a única opção de linguagem de programação, o Cobol, C e Natural por exemplo começaram a ficar “populares”.
Na baixa plataforma (ou plataforma distribuída, como diziam alguns profissionais), primeiro vieram as bibliotecas com várias “rotinas dentro” através da programação estrutural (com suas Procedures e Functions), depois nos sistemas “for Windows” tivemos (e ainda temos) as DLLs, EXEs etc. Mais à frente, veio a Programação a Orientação orientada a Objetos, com seus Namespaces, Classes e Métodos.
E com o tempo percebeu-se ainda que software era feito para negócios de empresas. Softwares precisavam estar aderentes à realidade operacional destas empresas. Então começou-se a pensar software mais sob uma ótica funcional.
E principalmente com os ERPs veio a ideia de dividir o sistema em módulos como Contabilidade, Tesouraria, RH, Financeiro etc. Cada módulo possuía como recursos as atividades do dia a dia dos departamentos das empresas, e estas atividades de cada departamento iam se tornando as funcionalidades de cada módulo.
Houve uma mescla de tudo isso, e hoje temos o conceito de Módulos e Funcionalidades.
/* Se você chegou até aqui na leitura do post, caso pense que o trecho acima é teórico demais e talvez, desnecessário, lhe convido a rever sua opinião. Tudo na área de software se dá por analogia com a vida real. Softwares resolvem problemas reais, e precisam espelhar-se no cenário real de negócio das empresas que possuem os problemas. Muitos de nós subestimamos isso, e ao invés de produzimos “soluções”, às vezes produzimos apenas “programas”. */
Exemplos de Módulos e Funcionalidades
Como citamos, um software será sempre um agrupamento de Módulos e Funcionalidades, organizados conforme a realidade do negócio onde encontra-se o problema que o software propõe-se a resolver.
Como exemplos de Módulos e Funcionalidades podemos citar:
- Módulo Estoque: Entrada de Material, Estorno de Entrada de Material, Estorno de Saída de Material.
- Módulo Produtos: Cadastro de Produto, Composição de Preço, Ativação de Produto.
- Módulo Mapas: Cadastro de Local, Associação de Estabelecimento a Local, Alteração de CEP.
- Módulo Financeiro: Realização de Pagamento, Estorno de Pagamento, Cadastro de Beneficiário.
São exemplos didáticos apenas. Essa definição sempre estará associada ao contexto de negócio no qual o software, enquanto solução, está inserido.
Acoplamento e Coesão em Módulos e Funcionalidades
É fundamental entender que todo projeto, absolutamente, começa na definição de Módulos e na definição de suas Funcionalidades. Ao menos deve ser assim.
Pensemos (como costumo fazer aqui no blog) em uma casa.
O cliente quer uma casa de três andares, com piscina. Dito isso ao Engenheiro, ele pensará a casa tendo como norte uma casa de três andares, com piscina. Ele não vai pensar primeiro em qual fechadura vai usar nas portas do banheiro, por exemplo.
Quando iniciamos um projeto de um software, devemos pensar assim. Começar pelo começo, do grande ao pequeno.
Imagine uma casa onde na cozinha tem um vaso sanitário, dentro da piscina tem um quarto, no sótão tem um terraço. Maluquice não?
E um software com funcionalidades de Realizar Pagamento a Fornecedores no Módulo de RH, ou a funcionalidade de Pagamento de Funcionários no módulo de Pagamento a Fornecedores?
São coisas que, do ponto de vista da realidade do negócio, do ponto de vista funcional, possuem afinidades?
São exemplos talvez exagerados, eu sei. Mas no dia a dia, talvez sem tanta distorção, isso é muito mais comum do que pensamos. Misturamos as responsabilidades dos Módulos, e só percebemos isso quando o sistema torna-se um Frankenstein.
Mas um sistema, conceitualmente falando, não são apenas módulos. Módulos tem Funcionalidades, conforme estamos vendo aqui.
Imaginemos ainda a tal casa citada. Vamos refletir.
Seria coerente colocar um bebedouro dentro da piscina? Você pode responder: “Porque não? Enquanto eu tomo banho de piscina eu fico com sede, e não posso beber água com cloro”.
Seria coerente colocar ar condicionado no sótão? Você pode responder: “Porque não? Tudo bem que eu quase não vou lá, mas quando vou lá no verão faz um super calor lá dentro!”.
Vamos para o software.
Seria coerente, numa funcionalidade de Cadastro de Funcionário no módulo de RH, colocarmos um comando (botão) de “Pagar Salário”? Você pode responder: “Porque não? Quem vai receber o salário não é o Funcionário?”.
Não seria melhor ter uma funcionalidade de Pagamento de Salários, onde seleciona-se um ou mais funcionários, e através de um único comando, efetuar o Pagamento a todos de uma única vez, e todas as regras de negócio pertinentes estarem associadas apenas a esta funcionalidade?
Ainda, seria coerente numa funcionalidade de Pagar Conta, colocar um grid para “Consultar Contas a Vencer nos próximos 120 dias”? Você pode responder: “Porque não? Talvez seja interessante saber, quando vou pagar uma conta, quais são as contas que vão vencer nos próximos quatro meses”.
Não seria melhor deixar a funcionalidade de Pagar Conta com recursos apenas para Pagar Conta, e disponibilizar um item de menu onde se tem uma funcionalidade (tela) para “Consulta de Contas a Vencer”, com campos para parametrização do período futuro, opções de exportação para Excel e PDF por exemplo?
A estrutura (modelo) conceitual de um software é como a estrutura de um livro
Um software é um livro vivo que mostra a estória de uma operação de negócio.
Imagine este livro sem capítulos. É um software sem módulos.
Imagine este livro com assuntos de capítulos distintos misturados. É um software com módulos muito acoplados e poucos coesos.
Imagine um capítulo com páginas sem títulos, parágrafos e alíneas. É um software sem funcionalidades.
Imagine um capítulo com trechos de páginas de outros capítulos. É um módulo com funcionalidades muito acopladas e poucos coesas.
/* O ápice da qualidade e maturidade na produção de software se dará o dia em que o código fonte contar esta estória (e também a história) com total clareza e organização. Isso não é viável ainda. Por agora, é apenas utopia. */
Concluindo
Não adianta termos as melhores ferramentas, os melhores computadores, o maior orçamento ou o maior prazo, se ignoramos os conceitos elementares.
Fazer software, do ponto de vista de Engenharia, é muito mais método e raciocínio aplicado através de boas práticas, do que domínio e aplicação das melhores tecnologias.
Frameworks, Linguagens de Programação, Ferramentas Case, Bancos de Dados etc. evoluem muito rápido, mas os profissionais às vezes esquecem que estes recursos são apenas ferramentas.
Não adianta ter a melhor chave de fenda, se ao usá-la o profissional deixa o parafuso frouxo.
Módulos e Funcionalidades pensados com baixo acoplamento e alta coesão é fator determinante para um sistema com menor probabilidade de ficar caótico após seu projeto e construção.
Se você gostou do conteúdo deste post, deixe seus comentários, para ajudar outras pessoas a encontrarem este material! 🙂
Grande abraço!