Arquivo

Textos com Etiquetas ‘POG’

[POG] Deveria lançar uma “excessão”

24 de fevereiro de 2012

Não preciso falar nada, o nome do teste diz tudo:

[TestMethod]
public void Deveria_lancar_uma_excessao_ao_obter_para_recusa_com_id_igual_a_zero()
{
    try
    {
        Transacao transacao = this.transacaoBO.ObtemParaRecusa(Guid.NewGuid(), 0);

        Assert.Fail("Deveria ser lançada uma ArgumentException.");
    }
    catch (ArgumentException ex)
    {
        Assert.AreEqual<string>(ex.Message, "ID da conta não pode ser menor ou igual a zero." + Environment.NewLine + "Parameter name: idComprador");
    }
}

Exceção mesmo é escrever código em português. Se fosse em inglês, esse atentado à lingua portuguesa teria sido evitado.

Se você não conhece POG (Programação Orientada a Gambiarras), leia esse artigo para entender melhor.

POG , ,

[POG] SendEmail ou EnviarEmail

19 de junho de 2011


Estou dando manutenção em sistema feito em .NET, corrigindo vários bugs e implementando algumas melhorias. Os autores do código não estão mais envolvidos no projeto.

Em uma página de formulário de contato, um e-mail é enviado para a equipe de atendimento e outro para o próprio cliente que preencheu o formulário de contato. Esses e-mails são enviados através de uma classe chamada Utils, através de dois métodos distintos SendEmail e EnviarEmail.

Vamos dar uma olhada no código C# da classe Utils:

public class Utils
{
  public static void SendEmail(string senderEmail, string senderName, string subject, string body, params string[] destinyEmails)
  {
    MailMessage mailMessage = new MailMessage();
    mailMessage.From = new MailAddress(senderEmail, senderName);
    mailMessage.Subject = subject;
    mailMessage.Body = body
    mailMessage.IsBodyHtml = true;

    foreach (string to in destinyEmails)
    {
      mailMessage.To.Add(to);
    }

    SmtpClient smtpClient = new SmtpClient(ConfigurationSettings.AppSettings["Email.Host"]);

    if (!string.IsNullOrEmpty(ConfigurationSettings.AppSettings["Email.User"]))
      smtpClient.Credentials = new System.Net.NetworkCredential(ConfigurationSettings.AppSettings["Email.User"], ConfigurationSettings.AppSettings["Email.Password"]);
    smtpClient.Send(mailMessage);
  }

  public static void EnviarEmail(string pEmail, string pAssunto, string Corpo)
  {
    try
    {
      string emailFrom = ConfigurationSettings.AppSettings["Email.From"];
      string NomeFrom = ConfigurationSettings.AppSettings["Email.Nome.From"];
      Model.Entities.Utils.SendEmail(emailFrom, NomeFrom, pAssunto, Corpo, new string[] { pEmail });
    }
    catch (Exception ex)
    {
      throw new Exception(ex.Message);
    }
  }

  // Outros métodos
}

O método SendEmail até que passa, mas daria para melhorar. Por exemplo, eu colocaria chaves no if da linha 18 para não confundir com a execução da linha 20.

Já o método EnviarEmail, nas linhas 23 a 35, tem uma lista de POGs:

  • Primeira coisa: por que o Pateta criou o método com esse nome? No mínimo esse método seria uma sobrecarga do método SendEmail.
  • O que é esse “p” como prefixo dos dois primeiros parâmetros? É para dizer que é um parâmetro? Nossa, bem mais eficaz que todo o intelisense do Visual Studio.
  • Legal esse terceiro parâmetro chamar Corpo. Esse nome é bem coerente com a convenção de nomenclatura de parâmetros.
  • Nas linhas 27 e 28 a declaração de duas variáveis locais emailFrom e NomeFrom, uma em camel case e outro em pascal case.
  • Na linha 29 uma chamada do método SendEmail com toda a hierarquia de namespace, sendo que o método chamado é da própria classse Utils.
  • Ainda na linha 29, olha que lindo que foi a passagem de parâmetros para: emailFrom, NomeFrom, pAssunto. Cada variável com uma convenção de nomenclatura diferente. O padrão é não seguir nenhum padrão.
  • Mais ainda na linha 29, no último parâmetro o Pateta criou uma array de um único elemento para passar o e-mail de destino da mensagem. No método SendEmail esse parâmetro está definido com a palavra-chave params, que permite que seja passado nenhum valor, um valor, n valores separados por vírgula ou um array.
  • E para finalizar em grande estilo, nas linhas 31 a 34, uma captura de exceção para colocar dentro de outra exceção e lançá-la de novo. Ou seja, só colocou lixo no stack trace.

Se você não conhece POG (Programação Orientada a Gambiarras), leia esse artigo para entender melhor.

POG ,

[POG] Refatorando a linha 3418

28 de dezembro de 2010

O que é pior que encontrar um método, como esse abaixo, que retorna explicitamente um valor booleano como resultado do teste de uma lógica condicional?

private bool ExibeContaCorrente(Formulario form)
{
    if (form.ExibeAgencia || form.ExibeContaCorrente)
    {
        return true;
    }
    else
    {
        return false;
    }
}

É encontrar esse método na linha 3418 de uma classe:

Se você não conhece POG (Programação Orientada a Gambiarras), leia esse artigo para entender melhor.

POG

[POG] Comparando retorno de operador lógico com booleano

13 de maio de 2010

Quer ver uma coisa que me irrita?

Imagina que você tenha uma variável chamada condition e em algum momento um valor booleano é atribuído a ela. Então você vai usar o valor dessa variável em uma lógica condicional, por exemplo um if.

Aí o Pateta me faz isso:

if condition == true
  # do stuff
end

A variável condition já é booleana, não precisa comparar com true! É igual fazer isso:

if (i > 0) == true
  # do stuff
end

Pra que serve essa segunda checagem? Para confirmar, ter certeza mesmo, que a expressão i > 0 realmente retornou true? Se for assim, então por que não testar se é true mais vezes?

if (((i > 0) == true) == true) == true
  # do stuff
end

Que tal fazer um loop e só parar de verificar quando der Stack Overflow?

POG ,

[POG] Mascarando dados sigilosos de cartão de crédito

28 de março de 2010

Se você não sabe o que é POG, veja esse post antes.

Imagine que você tenha uma string formatada como um XML, e nesse XML exista um nó com um dado sigiloso, por exemplo, o número de um cartão de crédito. Então você cria um método que recebe essa string e mais um parâmetro com o nome do nó que contém o dado sigiloso. O método irá retornar a mesma string substituindo o valor sigiloso por asteriscos (*).

Por exemplo, para a representação XML abaixo:

<prodis>
  <some_text>Prodis</some_text>
  <sensitive_data>4010098287290192</sensitive_data>
  <some_value>456</some_value>
</prodis>

Queremos o valor “4010098287290192″ presente no nó sensitive_data seja substituído por “****************”. A utilização desse método em C# seria assim:

string xml  = "<prodis>"
       xml += "  <some_text>Prodis</some_text>"
       xml += "  <sensitive_data>4010098287290192</sensitive_data>"
       xml += "  <some_value>456</some_value>"
       xml += "</prodis>"

xml = Util.MaskXmlData(xml, "sensitive_data");

/*
O valor da variável xml agora é:
<prodis>
  <some_text>Prodis</some_text>
  <sensitive_data>****************</sensitive_data>
  <some_value>456</some_value>
</prodis>
*/

Nem vamos entrar no mérito do porquê esse XML está em uma string. Vamos nos concentrar na resolução do problema em questão.

Veja agora como um Pateta implementou esse método utilizando técnicas POG:

{
  public static string MascaraCartaoXml(string xml, string tagAbertura, string tagFechamento)
  {
    string retorno = xml;

    int posicaoInicio = (xml.IndexOf(tagAbertura)) + (tagAbertura.Length);
    int posicaoFim = (xml.IndexOf(tagFechamento));
    string cartao = xml.Substring(posicaoInicio, posicaoFim - posicaoInicio);
    string cartaoMascarado = cartao;

    for (int i = 0; i < cartao.Length; i++)
    {
      cartaoMascarado = cartaoMascarado.Replace(cartao.Substring(i, 1), "*");
    }

    retorno = xml.Replace(tagAbertura + cartao + tagFechamento, tagAbertura + cartaoMascarado + tagFechamento);

    return retorno;
  }
}

Meus comentários a respeito:

  • Que fique bem claro que esse método é única e exclusivamente para mascarar dados de cartão (de crédito?). Qualquer outro texto que não seja cartão não poderá ser mascarado. Será que serve também para cartão telefônico ou cartão de Natal?
  • Você já viu algum XML bem formatado onde o nome da tag de abertura de um nó é diferente do nome da sua tag de fechamento? Talvez no mundo POG isso seja possível.
  • Preciso dizer alguma coisa sobre as linhas 9 a 14 ou posso somente dar risada?

POG , ,

POG: Programação Orientada a Gambiarras

28 de março de 2010

Programação Orientada a Gambiarras, ou somente POG, é uma técnica avançada de desenvolvimento de software que tem como base a utilização de todo tipo de gambiarra, remendo e tudo de pior que um código pode ter. POG se baseia em conceitos como duplicação de código, fluxos redundantes, tarefas desnecessárias e reinvenção de rodas.

A primeira POG que se tem notícia é datado de 1582 d.C. O nome desta POG hoje é chamada de Ano Bissexto e foi criada pelo Papa Gregório XIII. Esta POG foi aplicada quando descoberto que a Terra leva 365,25 dias para dar uma volta no Sol, porém nosso calendário tem apenas 365 dias, o que leva a uma diferença de 6 horas por ano. Ao invés de corrigir o “sistema” para que não houvesse essa diferença, a solução adotada pelo Papa foi: “A cada quatro anos, é só colocar mais um dia ali”.

Acredita-se que a POG está presente desde os primórdios da criação de software. Alguns até dizem que ela já existia desde a época de cartões perfurados. POG mantém sua evolução ao longo do tempo, onde perdurou com a programação estruturada e atingiu seu ápice com o surgimento da orientação a objetos.

Se você não conhece POG e não está entendendo nada, leia esse artigo para entender melhor.

No meu primeiro post havia mencionado que iria mostrar alguns códigos POG que tenho encontrado durante esses 10 anos que trabalho com desenvolvimento de software. Relutei quase um ano para tocar no assunto, tentando até certo ponto preservar os autores dos códigos POG que encontrei pela frente.

Mas outro dia me deparei com um trecho de código que me serviu de motivação para publicar os exemplos de POG que tenho guardado. Era um código em C# de um método que retornava um valor booleano indicando se uma requisição HTTP teve uma resposta com sucesso:

private bool IsResponseOK()
{
    return this.response.StatusCode == 200 ? true : false;
}

Uma versão em Ruby seria assim:

def response_ok?
  @response.code == 200 ? true : false
end

Preciso uma motivação maior do que essa para publicar os códigos POG? É claro que não vou citar o nome de ninguém aqui, mas vou chamá-los carinhosamente de Patetas.

Meu próximo post mostrará uma técnica POG avançada de substituição de caracteres em uma string.

Observação importante

Não estou aqui dizendo que sou um programador perfeito, que não cometo erros ou que escrevo o código mais limpo do mundo. Com certeza eu já fiz alguma POG, seja por falta de conhecimento ou por falta de opção. O ponto aqui é aprender com os erros, os seus e os dos outros.

Por outro lado, eu me esforço para aprimorar a qualidade do meu código a cada dia. Isso se dá com a prática do dia-a-dia, trocando experiências com outros desenvolvedores, lendo o código dos outros, fazendo programação pareada e estudando e lendo muito. Também sei que sou detalhista, sistemático e até certo ponto chato em relação à qualidade de código. Um código ruim me incomoda, mesmo que esse código produza o que se espera dele.

Além disso, todo e qualquer código POG que eu venha a publicar aqui foi escrito por desenvolvedores experientes (ou que se diziam experientes). Achar defeitos em código de um programador iniciante ou um estagiário é fácil, publicá-los seria puramente sacanagem.

Segunda observação

No blog The Daily WTF, na seção CodeSOD (Code Snippet Of the Day), vários trechos de código POG são publicados periodicamente e seus leitores contribuem enviando suas experiências. Se você já teve contato com alguma POG de algum Pateta por aí e quiser compartilhá-lo, pode me mandar que eu o publico.

POG ,