Princípios de desenvolvimento de software são um conjunto de regras e recomendações específicas que os engenheiros devem seguir durante a implementação do programa se quiserem escrever um código bonito, claro e de fácil manutenção. Não há varinha mágica que possa transformar uma mistura de variáveis, classes e funções em código perfeito, mas há algumas dicas e dicas que podem ajudar um engenheiro a determinar se ele está fazendo a coisa certa.
Vamos dar uma olhada nestas recomendações básicas. Alguns dos princípios abaixo são específicos de Python, mas a maioria não são.
Medir duas vezes e cortar uma vez
Pensei que esse é o princípio mais importante de todos. Se você aprender apenas um princípio com este post, deve ser este. Nós, desenvolvedores/arquitetos/ gestores, as pessoas lutam com falta de atenção, erros estúpidos e erros de impressão, problemas pessoais, mau humor e café frio. Nada disto é relevante – o problema tem de ser resolvido. Para mim, como engenheiro, este princípio significa escolher a solução certa para o problema, escolher a abordagem certa para o problema, escolher as ferramentas certas para resolver o problema, confiança na solução construída. Escolher aqui significa pensar um pouco, encontrar os recursos necessários, reunir a equipa certa, pensar no design, pensar na abordagem, definir tarefas, controlar o resultado e assumir a responsabilidade por isso. Isto é “Engenharia como está”. Acho que eu mesmo não estou pronto para descrevê-lo com palavras corretas.
Não se repita (DRY)
É um princípio bastante simples mas muito útil que diz que repetir a mesma coisa em lugares diferentes é uma má idéia. Antes de mais nada, está relacionado com a necessidade de mais suporte e modificação do código. Se algum fragmento de código é duplicado em vários lugares dentro de um programa, há uma alta probabilidade de duas situações catastróficas:
- Ao fazer mesmo pequenas alterações no código fonte, você precisa alterar o mesmo código em vários lugares. Será necessário mais tempo, esforço e atenção(muitas vezes não é fácil).
- O primeiro item segue o segundo. Você ou outro desenvolvedor da sua equipe pode acidentalmente perder uma das alterações (pode acontecer simplesmente fundindo ramos em vcs) e enfrentar os bugs subsequentes na aplicação. Estes bugs podem ser frustrantes para você porque você já ouviu dizer que tal bug já foi corrigido.
Neste sentido, há uma recomendação – se algum código for encontrado na listagem mais de duas vezes, ele deve ser colocado de uma forma separada. Esta é uma recomendação geral. Na verdade, você deve pensar em criar um método separado mesmo que você encontre uma repetição uma segunda vez.
Occam’s Razor
É uma idéia muito comum, que veio da filosofia para a programação. O princípio recebeu o seu nome do monge inglês William of Oakham. Este princípio diz: “As entidades não devem ser multiplicadas sem necessidade”. Na engenharia, este princípio é interpretado da seguinte forma: não há necessidade de criar entidades desnecessárias sem necessidade. Assim, é sempre uma boa ideia pensar primeiro sobre os benefícios de adicionar outro método/classe/ferramenta/processo, etc. Afinal, se você adicionar outro método/class/ferramenta/processo, etc. e não obtiver nenhuma vantagem além do aumento da complexidade, qual é o ponto?
Keep It Simple Stupid (KISS)
Este é um princípio muito semelhante ao acima mencionado, mas tem um significado ligeiramente diferente. Este princípio diz que o código deve ser o mais simples possível sem estruturas complexas, caso contrário irá complicar a depuração e manutenção do código. Além disso, será mais difícil para outro programador entender a lógica do código, o que por sua vez também exigirá tempo e esforço adicional. É por isso que você deve sempre tentar usar construções simples que resolvam o problema o máximo possível sem numerosos ramos, aninhamento profundo e estruturas de classe excessivamente sobrecarregadas. Ao fazer isso, você vai facilitar a sua vida e a dos seus colegas, pois a complexidade gera bugs. Lembre-se do que Peter Hintiens disse: “A simplicidade é sempre melhor que a funcionalidade”.
Você não vai precisar dela (YAGNI)
Um problema de que muitos programadores sofrem. O desejo de implementar de uma vez toda a funcionalidade necessária (e às vezes até desnecessária) desde o início do projeto. Ou seja, quando um desenvolvedor adiciona todos os métodos possíveis à classe desde o início e os implementa, e pode até nunca usá-los no futuro. Assim, de acordo com esta recomendação, em primeiro lugar, implemente apenas o que você precisa e, posteriormente, se necessário, amplie a funcionalidade. Desta forma, você economizará esforço, tempo e nervos ao depurar o código que não é realmente necessário.
Big Design Up Front
Antes de começar a desenvolver funcionalidades, você deve primeiro pensar na arquitetura da aplicação e projetar o sistema inteiro para detalhes suficientemente pequenos, e só então proceder à implementação de acordo com um plano pré-definido. O princípio tem o direito de existir, mas ultimamente, tem havido muitas críticas a isso. Em primeiro lugar, está relacionado com a obsolescência do plano durante a concepção e o seu funcionamento. Neste contexto, é necessário fazer as mudanças subsequentes ainda. Mas também tem vantagens inegáveis, na concepção correcta, é possível reduzir consideravelmente os custos de depuração e correcção de erros. Além disso, tais sistemas de informação, como regra geral, são mais lacônicos e arquitetonicamente corretos.
Otimização Preliminar
“Otimização Preliminar é a raiz de todo mal (ou pelo menos a maior parte dele) na programação” – Donald Knuth
Otimização é um processo muito correto e necessário para acelerar o programa, bem como para reduzir o consumo de recursos do sistema. Mas tudo tem o seu próprio tempo. Se a otimização for realizada nos estágios iniciais de desenvolvimento, pode fazer mais mal do que bem. Antes de mais nada, está ligado ao fato de que o desenvolvimento de um código otimizado requer mais tempo e esforço para o desenvolvimento e suporte. Neste caso, é preciso verificar com bastante frequência a correção da abordagem de desenvolvimento escolhida no início. É por isso que no início é mais rentável usar uma abordagem simples, mas não a mais otimizada. E mais tarde, ao estimar o quanto essa abordagem retarda o trabalho de uma aplicação, passe para um algoritmo mais rápido ou menos intensivo em recursos. Além disso, enquanto você implementar inicialmente o algoritmo mais otimizado, os requisitos podem mudar e o código irá para o lixo. Portanto, não há necessidade de perder tempo com a otimização prematura.
Principio do Menos Espantoso
Este princípio significa que seu código deve ser intuitivo e óbvio, e não surpreender outro desenvolvedor ao rever o código. Por exemplo, se o método é chamado de “fazer biscoitos”, mas você recebe batatas como resultado, esse código é ruim (obviamente). Além disso, você deve tentar evitar efeitos colaterais e documentá-los se você não puder evitá-los.
S.O.L.I.D.
“SOLID” é na verdade um grupo de princípios de design orientado a objetos. Cada letra em “SOLID” representa um dos princípios, que são:
- A responsabilidade única declara que cada módulo ou classe deve ter responsabilidade por uma única parte da funcionalidade fornecida pelo software e que a responsabilidade deve ser inteiramente encapsulada pela classe;
- Aberto-fechado declara que as entidades do software (classes, módulos, funções, etc.)) devem ser abertas para extensão, mas fechadas para modificação;
- A substituição da Liskov declara que a classe herdada deve complementar, e não substituir, o comportamento da classe base;
- A segregação de interface declara que nenhum cliente deve ser forçado a depender de métodos que não utiliza;
- A inversão de dependência diz que o programador deve trabalhar no nível da interface e não no nível da implementação.
Quando aplicados em conjunto, estes princípios ajudam um desenvolvedor a criar código que é fácil de manter e se estender no tempo.
Lei de Demeter
A idéia básica deste princípio é dividir as áreas de responsabilidade entre classes e encapsular a lógica dentro de uma classe, método ou estrutura. Várias recomendações podem ser distinguidas deste princípio:
- As classes ou entidades devem ser independentes
- Você deve tentar reduzir o número de conexões entre diferentes classes (o chamado acoplamento).
- As classes associadas devem estar em um módulo/pacote/diretório (também conhecido como coesão.
Seguir esses princípios, a aplicação torna-se mais flexível, compreensível e fácil de manter.
Conclusão
Caminhos desenvolvedores, vamos ser engenheiros! Vamos pensar em projetar e construir sistemas robustos e bem implementados, ao invés de crescer monstros orgânicos. Os princípios listados são altamente correlacionados e conectados em sua essência. Claro, eu não os criei, mas um pequeno lembrete não faz mal, pelo menos minha memória não é definitivamente perfeita.
Livros recomendados
- Código Limpo de Robert C. Martin
- Arquitetura Limpa de Robert C. Martin