Boas Práticas Nathan Geeksman

Convention over configuration: o princípio que reduz decisões desnecessárias

Convention over configuration: o princípio que reduz decisões desnecessárias

Convention over configuration: o princípio que reduz decisões desnecessárias

Introdução

O desenvolvimento de software é um processo complexo e multifacetado, envolvendo inúmeras decisões técnicas ao longo de sua execução. No entanto, muitos desses passos podem ser simplificados através da adoção de certos princípios arquiteturais. Neste artigo, vamos explorar a "convenção sobre configuração" - um conceito fundamental na criação de software eficiente e escalável.

No contexto atual de desenvolvimento de software, a complexidade dos sistemas em evolução torna cada vez mais crítico o gerenciamento de recursos e configurações. Muitas vezes, isso resulta em uma sobrecarga desnecessária para os desenvolvedores, que precisam tomar decisões rotineiras sobre como configurar suas aplicações.

Nesse artigo, vamos mergulhar no mundo das convenções de configuração, destacando as vantagens desse princípio e como ele pode ser aplicado em práticas de desenvolvimento. Ao final da leitura, você entenderá melhor como a "convenção sobre configuração" pode reduzir decisões desnecessárias no seu próprio projeto, tornando-o mais eficiente e fácil de manter.

O que é e por que importa

A "convenção sobre configuração" (Convention over Configuration, ou CxC) é um princípio arquitetural que estabelece regras predefinidas para a configuração de sistemas de software, reduzindo assim a necessidade de decisões explícitas por parte do desenvolvedor. Essa abordagem surgiu como resposta ao problema crescente da sobrecarga configuracional associado ao aumento da complexidade dos sistemas em evolução.

Com o passar do tempo, os sistemas de software tornaram-se cada vez mais sofisticados e flexíveis, exigindo uma grande quantidade de configurações para funcionarem corretamente. No entanto, muitas dessas configurações são necessárias apenas por casos específicos ou em ambientes de desenvolvimento diferentes, tornando-as um fardo para os desenvolvedores, que precisam lidar com elas.

A CxC visa eliminar esses problemas configuracionais desproporcionados, adotando regras predefinidas em vez da configuração explícita. Isso é alcançado ao estabelecer padrões de configuração implícitos, tornando a configuração mais rápida e menos propensa a erros.

A motivação por trás do CxC está na eliminação dos custos associados à gestão da complexidade configuracional. Esses custos incluem o tempo perdido com a análise de configurações, o potencial de falhas causadas por configurações inadequadas e a dificuldade em manter as configurações atualizadas para novas versões ou mudanças na arquitetura do sistema.

Ao adotar a convenção sobre configuração, os desenvolvedores podem focar-se nas partes mais importantes da aplicação, enquanto a CxC se encarga de fornecer uma base configuracional estável e eficiente.

Como funciona na prática

A CxC funciona ao estabelecer padrões de configuração implícitos, que são configurados implicitamente quando um recurso ou funcionalidade é adicionado ao sistema. Esses padrões podem ser definidos por meio de módulos, plugins ou carregadores, que fornecem as regras e comportamentos de configuração para o sistema.

  • Padrões de configuração implícitos: Os desenvolvedores especificam os padrões de configuração que devem ser seguidos por todos os recursos e funcionalidades que são adicionados ao sistema. Esses padrões podem incluir configurações como endereços de servidor, portas de conexão, ou outros detalhes de configuração.
  • Módulos, plugins ou carregadores: Os desenvolvedores criam módulos, plugins ou carregadores que implementam os padrões de configuração implícitos. Esses componentes são responsáveis por configurar implicitamente os recursos e funcionalidades ao adicioná-las ao sistema.
  • Integração com o sistema: O sistema é projetado para se integrar com os módulos, plugins ou carregadores que implementam as regras de configuração implícitos. Isso permite que o sistema configure implicitamente os recursos e funcionalidades conforme estabelecido pelos padrões de configuração.
  • Configuração explícita: Embora a CxC esteja focada em configurar implicitamente os recursos e funcionalidades, ainda é possível realizar configurações explícitas quando necessário. Isso é feito por meio da intervenção direta do desenvolvedor na configuração do sistema.

Ao usar a convenção sobre configuração, o desenvolvedor pode evitar a sobrecarga configuracional associada à complexidade dos sistemas em evolução, focando-se nas partes mais importantes da aplicação.

Exemplo real

O exemplo abaixo ilustra como a convenção sobre configuração pode ser implementada em um sistema de gerenciamento de conteúdo, utilizando Python e o framework Flask.

config_padrao = {
    'banco': 'sqlite',
    'host': 'localhost',
    'porta': 5432,
    'usuario': 'root',
    'senha': ''
}

class BancoDeDados:
    def __init__(self, config):
        self.config = config

    def conectar(self):
        # Conectar ao banco de dados com base na configuração padrão
        if self.config['banco'] == 'sqlite':
            return sqlite3.connect(self.config['host'])
        elif self.config['banco'] == 'mysql':
            return mysql.connector.connect(
                host=self.config['host'],
                database=self.config['banco'],
                user=self.config['usuario'],
                password=self.config['senha']
            )
        else:
            raise ValueError('Banco de dados não suportado')

def carregar_configuracao_padrao():
    return config_padrao

app = Flask(__name__)
config = carregar_configuracao_padrao()
banco_de_dados = BancoDeDados(config)

@app.route('/conteudo', methods=['GET'])
def buscar_conteudo():
    conexao = banco_de_dados.conectar()
    # Realizar consulta no banco de dados e retornar os resultados
    return jsonify(conteudos)

Nesse exemplo, a convenção sobre configuração é implementada através da criação de um módulo BancoDeDados que usa a configuração padrão para conectar ao banco de dados. O carregador de configuração carregar_configuracao_padrao() é responsável por fornecer a configuração padrão, e o sistema de gerenciamento de conteúdo integra essa configuração com o módulo do banco de dados.

Boas práticas

Utilizar um módulo de configuração isolado

Isolar a lógica de configuração em um módulo separado permite uma fácil manutenção e atualização das configurações.

Evitar configurações difusas

Evitar que as configurações sejam difusas, isto é, não espalhar configurações pelo código. Utilizar um único ponto para acessar a configuração.

Armadilhas comuns

Dependência cícica entre módulos de configuração e sistema de gerenciamento de conteúdo

Manter o carregador de configuração separado do sistema de gerenciamento de conteúdo pode evitar dependências cícicas.

Sobrecarga de configurações redundantes

Evitar a sobrecarga de configurações redundantes, como quando uma configuração é definida em dois lugares diferentes.

Conclusão

A implementação do princípio de convenção sobre configuração pode trazer benefícios significativos, como a redução de decisões desnecessárias e a melhoria da manutenibilidade do código. Além disso, é importante evitar dependências cícicas entre módulos de configuração e sistema de gerenciamento de conteúdo, além de minimizar a sobrecarga de configurações redundantes.

Para adentrar nesse conceito, é recomendável explorar a implementação do padrão de projeto "Factory Method" ou "Abstract Factory", que podem ajudar a isolar a lógica de configuração e melhorar a reutilização de código. Além disso, estudar sobre os frameworks e bibliotecas que permitem a injeção de dependência de configurações pode fornecer mais ferramentas para implementar a convenção sobre configuração.

A prática da programação orientada a objetos também deve ser explorada, pois ajuda a organizar o código em classes responsáveis por suas próprias configurações e dependências. Isso pode contribuir para uma arquitetura mais modular e escalável.

Referências

  • Fowler, M. Injeção de Dependência. Disponível em: https://martinfowler.com/articles/injection.html. Acesso: 2024.
  • Martin Fowler. Factory Method. Disponível em: https://martin.kleppner.org/posts/2016-05-10-factory-method-pattern/. Acesso: 2024.
  • OWASP. Dicas para uma Arquitetura de Segurança. Disponível em: https://owasp.org/www-pdf-archive/OWASP%20Top%2010%20Security%20Risks_2017.pdf. Acesso: 2024.
  • Ericsson, B. et al. Do You Need a Framework?. Disponível em: https://12factor.net/why/. Acesso: 2024.
  • Fowler, M. Refatoração. Disponível em: https://martinfowler.com/books/refactoring.html. Acesso: 2024.