Má prática - alternar entre maiúsculas e minúsculas para definir o ambiente

32

Nos últimos três anos em que trabalhei como desenvolvedor, vi muitos exemplos em que as pessoas usam uma instrução switch para definir o caminho (tanto no back-end quanto no front-end) para um URL. Abaixo está um exemplo disso:

Exemplo de backend (C #):

public static string getHost(EnvironmentEnum environment){
    var path = String.Empty;
    switch (environment)
    {
        case EnvironmentEnum.dev:
            path = "http://localhost:55793/";
            break;
        case EnvironmentEnum.uat:
            path = "http://dev.yourpath.com/";
            break;
        case EnvironmentEnum.production:
            path = "http://yourpath.com/";
            break;
    }
    return path;
}

Exemplo de front-end (JavaScript):

(function () {
    if (window.location.host.indexOf("localhost") !== -1) {
        window.serviceUrl = "http://localhost:57939/";
    }
    else if (window.location.host.indexOf("qa") !== -1) {
        window.serviceUrl = "http://dev.yourpath.com/";
    }
    else {
        window.serviceUrl = "http://yourpath.com/";
    }
})();

Foi discutido se é uma prática boa ou ruim, e acho que é uma prática ruim, porque devemos evitar esse tipo de código e definir uma configuração adequada. Mas, para ser sincero, eu realmente não sei a resposta correta e por que ela não é recomendada e qual é a maneira correta de implementar isso.

alguém pode explicar os prós e os contras da prática acima?

gon250
fonte
13
Essa linha sozinha não é ótima. path = " yourpath.com "; A configuração deve ser externa ao código.
Paparazzo
2
De uma perspectiva pura de revisão de código, a Dictionaryé uma maneira muito mais limpa de codificar isso em C #. Consulte ideone.com/45g5xO . Ou no JS, use um objeto antigo, consulte jsfiddle.net/1ouhovqq .
Danny Beckett
4
o que acontece se o nome da sua empresa mudar para algo que contenha "qa"?
user253751
Lembre-se de que se você usar um arquivo de configuração, ele precisará ser controlado no controle do código-fonte .... Qualquer um que precisar editar o arquivo de configuração várias vezes ao dia quando você configurar novas máquinas de teste. Eu ainda acho que um arquivo de configuração é o melhor, mas você pode primeiro procurar um arquivo chamado Ambiente com base antes de olhar para o arquivo de configuração detaul.
31715 Ian
1
Eu não acho que você deva sair chamando as coisas de má prática, se você não pode quantificar por que você acha que é uma má prática #
217 Roy Roy

Respostas:

81

O código que funciona para você e é fácil de manter é, por definição, "bom". Você nunca deve mudar as coisas apenas por obedecer à idéia de "boa prática" de alguém, se essa pessoa não puder apontar qual é o problema do seu código.

Nesse caso, o problema mais óbvio é que os recursos são codificados em seu aplicativo - mesmo que sejam selecionados dinamicamente, eles ainda são codificados. Isso significa que você não pode alterar esses recursos sem recompilar / reimplementar seu aplicativo. Com um arquivo de configuração externo, você apenas precisará alterar esse arquivo e reiniciar / recarregar seu aplicativo.

Se isso é ou não um problema, depende do que você faz com ele. Em uma estrutura Javascript que é redistribuída automaticamente a cada solicitação, não há problema algum - o valor alterado será propagado para todos os usuários na próxima vez em que usarem o aplicativo. Com uma implantação local em uma linguagem compilada em um local inacessível, é realmente um grande problema. A reinstalação do aplicativo pode levar muito tempo, custar muito dinheiro ou ter que ser feita à noite para preservar a disponibilidade.

Se os valores codificados são ou não um problema depende se sua situação é mais parecida com o primeiro exemplo ou mais com o segundo exemplo.

Kilian Foth
fonte
15
Eu amo o seu primeiro parágrafo. Claro, você segue com ... apontando quais são os problemas ... mas a idéia de que "isso é ruim porque o blog XYZ disse isso" é a causa de mais códigos ruins do que realmente impedem.
corsiKa
5
Os iniciantes devem receber princípios testados pelo tempo para viver, não simplesmente o relativismo "se funcionar para você, então está tudo bem" . Acho que não estou errado em dizer que os valores do ambiente codificado são absolutamente uma má prática sob qualquer luz.
Tulains Córdova
3
@ jpmc26: Obviamente, você está assumindo que a implantação do código do lado do servidor não é trivial e também que existe algum processo separado pelo qual os valores de configuração podem ser atualizados com menos sobrecarga. Nem é necessariamente verdade. Muitas lojas têm muito pouca sobrecarga em seus processos de implantação. Por outro lado, existem algumas lojas nas quais as alterações na configuração têm basicamente tanta sobrecarga quanto a implantação do código alterado. (Validação, necessitando de aprovação de um monte de pessoas, etc.). As preocupações com a duplicação são definitivamente válidas.
22415 Kevin Kathcart
2
Com as configurações do ambiente combinadas com o código do aplicativo, você é um erro lógico - ou alteração imprevista no ambiente de execução - longe de atingir o teste de produção, ou produção de teste, ou alguma outra combinação inesperada e possivelmente catastrófica. Manter propriedades específicas do ambiente separadas do código em C # geralmente é trivial. Por que correr um risco desnecessário?
John M Gant
1
@ user61852 "Acho que não estou errado em dizer que os valores do ambiente codificado são absolutamente uma prática ruim sob qualquer luz". analisa como "valores do ambiente de codificação embutida sempre são uma prática ruim" Se é sempre uma prática incorreta, sempre deve ser possível identificar pelo menos um problema que os valores do ambiente de codificação embutida causam.
Emory
14

Você está absolutamente certo ao pensar que esta é uma má prática. Eu já vi isso no código de produção, e ele sempre volta para te morder.

O que acontece quando você deseja adicionar outro ambiente? Ou mudar seu servidor de desenvolvimento? Ou você precisa fazer o failover para um local diferente? Você não pode porque sua configuração está diretamente vinculada ao código.

A configuração deve ser forçada a sair do código e entrar no próprio ambiente. É um princípio de um aplicativo de doze fatores ( http://12factor.net/config ), mas é uma boa prática para qualquer aplicativo. Você pode achar que as variáveis ​​de ambiente não são apropriadas para a sua situação; nesse caso, sugiro que você armazene essa configuração em um banco de dados de arquivo de configuração ao lado do código (mas não com o check-in).

mgw854
fonte
Se você não acompanhar o arquivo de configuração, como saber se o arquivo de configuração que você possui é válido para a versão do software que você acabou de fazer check-out do seu VCS. (ou seja, um arquivo de configuração untracked não é diferente de um arquivo de origem untracked - você não pode construir e implantar a partir VCS check-out sem ele)
mattnz
Não discordo que um arquivo de configuração não rastreado seja uma proposta difícil. A maneira como lidei com isso antes é dupla: uma, o binário para implantação também contém um esquema XML que define sua configuração (para que você possa verificar se um determinado arquivo de configuração funcionará). Segundo, os arquivos de configuração para cada ambiente foram armazenados em um sistema de controle de documentos com pastas diferentes para cada ambiente. Algo semelhante poderia ser feito no Git com branches - versão controlada, mas discriminada por código sem ambiente.
mgw854
5

Por um lado, (como outros já mencionaram), é uma má idéia, porque você está vinculando detalhes da implementação ao seu código. Isso torna difícil mudar as coisas.

Conforme mencionado nesta resposta , se você deseja adicionar um novo ambiente agora, é necessário atualizar seu código em qualquer lugar , em vez de apenas adicionar seu programa a um novo ambiente.

Existe outra falha grave ao fazer isso no seu código Javascript: você está expondo os internos da sua empresa a possíveis invasores. Claro, você pode estar protegido por um firewall, mas ainda pode ter um funcionário insatisfeito ou alguém que liberta um vírus.

Más notícias.

A melhor coisa a fazer é definir sua configuração a partir do ambiente (como na resposta vinculada anteriormente, o Twelve-Factor App oferece ótimos conselhos sobre o assunto). Existem várias maneiras de fazer isso, dependendo do seu idioma. Um dos mais fáceis (geralmente) é apenas definir variáveis ​​de ambiente. Depois, basta alterar as variáveis, dependendo de onde você está executando - seja uma caixa de desenvolvimento local, qa ou produção. Outra opção é armazenar os valores em um.ini arquivo ou JSON. Outra alternativa seria armazenar seus valores de configuração como código real. Dependendo do idioma ou do ambiente em uso, isso pode ou não ser uma boa ideia.

Mas o objetivo final é permitir que você use uma base de código, solte-a em qualquer máquina com arquitetura / conectividade suportada e possa executá-la sem modificar o código de nenhuma maneira.

Wayne Werner
fonte
1

E se eu quiser executar o back-end em minha própria máquina, mas não na porta 55793, por exemplo, se eu estiver executando várias versões ao mesmo tempo para compará-las? E se eu quiser executar o back-end do aplicativo em uma máquina, mas acessá-lo de outra? E se eu quiser adicionar um quarto ambiente? Como outros já apontaram, você deve recompilar apenas para alterar a configuração básica.

A abordagem que você descreveu pode ter funcionado na prática para sua equipe até agora, mas é inútil e restritiva. Um sistema de configuração que permite que parâmetros como esse caminho sejam definidos arbitrariamente em um arquivo de configuração central é muito mais flexível do que um que fornece apenas opções fixas, e que vantagem você ganha com a abordagem da instrução switch? Nenhum!

PeterAllenWebb
fonte
0

É uma má prática .

Um princípio básico do design de software: não codifique valores de configuração dentro de seus programas. Isto é especialmente verdade para qualquer coisa que tenha uma chance razoável de mudar no futuro.

O código do programa que você desenvolve deve ser o mesmo código que entra em qualquer ambiente, como teste de controle de qualidade, UAT e produção. Se alguém precisar alterar a configuração posteriormente porque o ambiente mudou ou precisar usá-la em um novo ambiente, tudo bem. Mas eles nunca devem tocar no código do seu programa para fazer isso. E você não deve ter versões diferentes de código para cada ambiente. Se o seu programa mudou desde que foi testado, você não testou essa versão. Pergunte a qualquer engenheiro de software, qualquer profissional de controle de qualidade de software, qualquer profissional de gerenciamento de projetos de TI, qualquer auditor de TI.

Alguém pode mover o teste para outro servidor. Alguém pode decidir também querer um ambiente de treinamento do usuário ou um ambiente para demonstrações de vendas. Eles não precisam ir a um programador para configuração administrativa.

O software deve ser flexível e robusto o suficiente para lidar com situações inesperadas, dentro do razoável.

Além disso, o software não deve ser escrito simplesmente, no entanto, parece mais fácil para você no momento. O custo do desenvolvimento de software é pequeno comparado ao custo de manutenção de software ao longo de sua vida útil. E digamos que daqui a um ano, você pode não ser a pessoa que trabalha nesse código. Você deve estar pensando no que está deixando para o próximo pobre tolo que tem que pegar qualquer bagunça que tenha deixado para trás, talvez anos depois de ter passado por pastos mais verdes. Ou você pode ser o único que pega o código anos depois, sem acreditar no que fez na época.

Codifique as coisas corretamente, da melhor maneira possível. É menos provável que se torne um problema mais tarde.

WarrenT
fonte