O que é um ajudante? É um padrão de design? É um algoritmo?

40

Talvez um pouco irônico, mas como não consigo encontrar esta resposta em nenhum lugar pelo Google, por isso, para garantir que a Engenharia de Software tenha a resposta:

O que é um ajudante?

Eu vi o nome sendo usado em todos os lugares (nomes de módulos, nomes de classes, nomes de métodos), como se a semântica fosse profunda e significativa, mas no contexto da Ciência da Computação (embora eu não seja formado), eu ' nunca vi uma descrição ou definição em lugar algum!

É um padrão de design? É um algoritmo? Certa vez, trabalhei em um programa no qual o módulo e a classe eram chamados de algo como algo que ajuda (onde algo também era genérico) e prontamente o renomeei para algo que fazia sentido para mim, mas sinto que estou perdendo algo aqui!

Aaron Hall
fonte
9
Helper é o que você chama de algo quando não sabe como chamá-lo, mas conhece um de seus amigos. É como chamá-lo de 'amigo de Zack' em vez de Aaron. Duplo mais ruim.
David.pfx
Um ajudante é qualquer membro privado, até o isomorfismo.
Thomas Eding
@ThomasEding desculpe-me por voltar três anos depois - mas já vi muitos membros "públicos" chamados "helper", incluindo interfaces. Eu gostaria de uma fonte para sua definição (quanto maior a qualidade, melhor), porque isso definitivamente me daria uma noção de mais odores de código.
Aaron Hall

Respostas:

63

Uma classe Helper é um cheiro de código menos conhecido, em que um codificador identificou algumas operações diversas e comumente usadas e tentou torná-las reutilizáveis ​​agrupando-as em um agrupamento não natural. Os desenvolvedores sucessivos entraram no projeto e não perceberam que a classe auxiliar existe e, consequentemente, reescreveram as mesmas operações comuns, ou até criaram mais classes Helper.

Mas, sério, o principal problema com as classes Helper é que elas geralmente são operações que agem em uma classe específica, o que obviamente significa em termos de OO que eles estão sofrendo de um caso agudo de Feature Envy . Essa falha em empacotar o comportamento com os dados nos quais atua é por isso que os desenvolvedores frequentemente (na minha experiência) não conseguem encontrá-lo.

Além disso, como você já identificou SomethingSomethingHelper é realmente um nome terrível. Não é descritivo e não dá uma idéia real de que tipo de operações a classe faz (ajuda?), O que também significa que não é óbvio ao adicionar novos comportamentos, independentemente de pertencerem ou não à classe Helper. Eu dividiria essas classes de acordo com o comportamento relacionado que agrupa logicamente e depois renomeia as novas classes para refletir o que elas fazem.

Cochese
fonte
9
Certamente esse SomethingSomethingHelpernão é o nome real da classe. Quer se trate de um cheiro de código ou não, isso depende de quão específica é a classe auxiliar, pois classes auxiliares como Mathessas não são de modo algum um cheiro de código.
Robert Harvey
10
@RobertHarvey - Enh, a maioria dos que eu vi ter sido nomeado SomethingSomethingHelper. Inferno, estou vendo uma classe agora nomeada HelperMethodsno <company>.Helpersespaço para nome. Para mim, uma Helperclasse está no mesmo balde que *Manager.
Telastyn
8
@Telastyn: Talvez seja uma experiência, então. Examinei as classes auxiliares no meu projeto atual (existem várias) e todas elas têm nomes significativos. Existe apenas um sufixo Helper, e acho que é para desambiguá-lo de uma classe no .NET Framework com o mesmo nome. Eu consideraria *Helperaceitável se *fosse algo significativo. HelperMethodsé apenas uma falha de imaginação; deve haver pelo menos baldes conceituais específicos.
Robert Harvey
4
@RobertHarvey - Você provavelmente está certo. Toda a minha carreira usando linguagens modernas foi arruinando trens.
Telastyn
11
Há um subconjunto deles, chamado "funções auxiliares", que são realmente úteis e um bom padrão. Por exemplo, um conjunto comum de linhas que, de outra forma, precisaria ser repetido em uma função - um exemplo de onde elas aparecem é quando você precisa de um do..whileloop em Python, que a linguagem não suporta (veja o segundo exemplo aqui ). Outra seria uma estrutura if / elif /.../ else, mas é necessário repetir um caso na parte superior e inferior. Se possível, eles devem ser tornados locais para essa função, e geralmente não são chamados de "auxiliares".
Izkata
5

Um auxiliar é uma classe ou método adicional inofensivo, desde que complemente um componente externo. Quando faz o contrário, indica um design incorreto porque o código foi excluído de sua autoridade, se houver alguma autoridade.

Aqui está um exemplo de um auxiliar inofensivo, eu uso um método chamado FindRepque conta o número de zeros à esquerda.

digits = digits.Remove(0, TextHelper.FindRep('0', digits, 0, digits.Length - 2));

O método auxiliar é muito simples, mas muito inconveniente para copiar e colar, e a estrutura não fornece nenhuma solução.

public static int FindRep(char chr, string str, int beginPos, int endPos)
{
    int pos;

    for (pos = beginPos; pos <= endPos; pos++)
    {
        if (str[pos] != chr)
        {
            break;
        }
    }

    return pos - beginPos;
}

E aqui está um exemplo de um mau ajudante:

public static class DutchZipcodeHelper
{
    public static bool Validate(string s)
    {
        return Regex.IsMatch(s, @"^[1-9][0-9]{3}[A-Z]{2}$", RegexOptions.IgnoreCase);
    }
}

public class DutchZipcode
{
    private string value;

    public DutchZipcode(string value)
    {
        if (!DutchZipcodeHelper.Validate(value))
        {
            throw new ArgumentException();
        }

        this.value = value;
    }

    public string Value
    {
        get { return value; }
    }
}
Leopold Asperger
fonte
-1

Minha empresa costumava usar a metodologia da classe Base / Helper, onde cada objeto teria duas classes. Você teria uma classe Person que continha todas as propriedades e definições da classe e uma classe PersonHelper que continha todos os métodos, instruções SQL e lógica que manipulavam a classe Person. Isso funcionou bem para nós, porque todos os nossos aplicativos usam instruções SQL para manipular dados e foi muito fácil encontrar e modificar as instruções SQL conforme necessário.

Desde então, seguimos em frente e agora colocamos tudo na classe Pessoa / Base. Paramos de usar a convenção de nomenclatura Helper porque queríamos ter menos arquivos em nossos projetos. Além disso, o tamanho de alguns nomes de classe estava ficando fora de controle. ri muito.

Não é um ótimo exemplo, mas você entendeu.

s = CompanyName.PersonHelper.GetPerson()
s = CompanyName.Person.GetPerson()

Não estou dizendo que usar a convenção de nomenclatura auxiliar é a solução perfeita, mas funcionou para nós por alguns anos.

Brian
fonte
2
Você não explicou o porquê.
Robert Harvey
2
Sim, eu também gostaria dessa explicação.
Aaron Hall
@AaronHall Considere uma coisa boa que você não entenda a escolha deles.
Leopold Asperger