Cos'è un aiutante? È un modello di design? È un algoritmo?


40

Forse un po 'ironico, ma poiché non riesco a trovare questa risposta da nessuna parte tramite Google, quindi per garantire che Software Engineering abbia la risposta:

Cos'è un aiutante?

Ho visto il nome usato ovunque (nomi dei moduli, nomi delle classi, nomi dei metodi), come se la semantica fosse profonda e significativa, ma nel contesto dell'Informatica (anche se non ho una laurea), io " non ho mai visto una descrizione o una definizione da nessuna parte!

È un modello di design? È un algoritmo? Una volta ho lavorato su un programma in cui il modulo e la classe erano entrambi chiamati Somethingsomethinghelper (dove qualcosa era anche abbastanza generico) e l'ho prontamente ribattezzato in qualcosa che aveva senso per me, ma sento che mi manca qualcosa qui!


9
Helper è ciò che chiami qualcosa quando non sai come chiamarlo ma conosci uno dei suoi amici. Un po 'come chiamarti "amico di Zack" invece di Aaron. Doppio più cattivo.
david.pfx,

Un aiutante è qualsiasi membro privato, fino all'isomorfismo.
Thomas Eding,

@ThomasEding mi dispiace tornare 3 anni dopo, ma ho visto molti membri "pubblici" chiamati "helper", comprese le interfacce. Vorrei una fonte per la tua definizione (migliore è la qualità migliore) perché ciò mi darebbe sicuramente un senso per più odori di codice.
Aaron Hall,

Risposte:


63

Una classe Helper è un odore di codice meno noto in cui un programmatore ha identificato alcune operazioni varie di uso comune e ha tentato di renderle riutilizzabili raggruppandole in un raggruppamento innaturale. Gli sviluppatori successivi sono quindi entrati nel progetto e non si sono resi conto dell'esistenza della classe helper, e di conseguenza hanno riscritto le stesse operazioni comuni o addirittura creato più classi Helper.

Ma seriamente, il problema principale con le classi Helper è che di solito sono operazioni che agiscono su una classe specifica, il che ovviamente significa in termini di OO che stanno soffrendo di un caso acuto di Feature Envy . L'incapacità di impacchettare il comportamento con i dati su cui agisce è il motivo per cui gli sviluppatori così spesso (nella mia esperienza) non riescono a trovarlo.

Inoltre, poiché hai già identificato SomethingSomethingHelper è in realtà un nome terribile. Non è descrittivo e non ti dà una reale idea di quale tipo di operazioni fa la classe (aiuta?), Il che significa anche che non è ovvio quando si aggiungono nuovi comportamenti che appartengano o meno alla classe Helper. Vorrei suddividere tali classi lungo le linee del comportamento correlato che raggruppano logicamente insieme, quindi rinominare le nuove classi per riflettere ciò che fa.


9
Abbastanza sicuro che SomethingSomethingHelpernon sia il vero nome della classe. Che si tratti o meno di un odore di codice dipende da quanto sia specifica la classe helper, poiché classi come helper Mathnon sono affatto un odore di codice.
Robert Harvey,

10
@RobertHarvey - Enh, la maggior parte di quelli che ho visto sono stati nominati SomethingSomethingHelper. Diavolo, sto guardando una classe in questo momento chiamata HelperMethodsnello <company>.Helpersspazio dei nomi. Per me, una Helperclasse è nello stesso secchio di *Manager.
Telastyn,

8
@Telastyn: forse è un'esperienza, quindi. Ho esaminato le classi di supporto nel mio progetto attuale (ce ne sono diverse) e hanno tutti nomi significativi. Ce n'è solo uno a cui è stato aggiunto il suffisso Helpere penso che sia quello di chiarire la sua ambiguità da una classe in .NET Framework con lo stesso nome. Considererei *Helperaccettabile se *fosse qualcosa di significativo. HelperMethodsè solo un fallimento dell'immaginazione; ci dovrebbero essere almeno specifici secchi concettuali.
Robert Harvey,

4
@RobertHarvey - Probabilmente hai ragione. Tutta la mia carriera nell'uso delle lingue moderne ha ripulito i disastri dei treni.
Telastyn,

1
C'è un sottoinsieme di questi, chiamati "funzioni di supporto", che sono effettivamente utili e un buon modello. Ad esempio, un insieme comune di linee che altrimenti dovrebbero essere ripetute all'interno di una funzione - un esempio di dove vengono visualizzate è quando hai bisogno di un do..whileciclo in Python, che la lingua non supporta (vedi il secondo esempio qui ). Un'altra sarebbe una struttura if / elif /.../ else, ma è necessario ripetere un caso in alto e in basso. Se possibile, dovrebbero essere resi locali a tale funzione, tuttavia, e generalmente non effettivamente chiamati "helper".
Izkata,

5

Un helper è una classe o un metodo aggiuntivo innocuo, purché integri un componente esterno. Quando fa il contrario, allora indica una cattiva progettazione perché il codice è stato escluso dalla sua autorità, se esiste alcuna autorità.

Ecco un esempio di un aiuto innocuo, uso un metodo chiamato FindRepche conta il numero di zeri iniziali.

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

Il metodo helper è molto semplice, ma molto scomodo da copiare e incollare e il framework non fornisce alcuna soluzione.

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;
}

Ed ecco un esempio di un cattivo aiuto:

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; }
    }
}

-1

La mia azienda utilizzava la metodologia di classe Base / classe Helper in cui ogni oggetto avrebbe avuto due classi. Avresti una classe Person che conteneva tutte le proprietà e le definizioni della classe e una classe PersonHelper che conteneva tutti i metodi, le istruzioni SQL e la logica che manipolavano la classe Person. Questo ha funzionato bene per noi perché tutte le nostre applicazioni usano istruzioni SQL per manipolare i dati ed è stato molto facile per noi trovare e modificare le istruzioni SQL in base alle esigenze.

Da allora siamo passati e ora abbiamo inserito tutto nella classe Persona / Base. Abbiamo smesso di usare la convenzione di denominazione Helper perché volevamo avere meno file nei nostri progetti. Inoltre, la lunghezza di alcuni dei nomi delle classi stava andando fuori controllo. lol.

Non è un ottimo esempio ma hai avuto l'idea.

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

Non sto dicendo che usare la convenzione di denominazione degli aiutanti sia la soluzione perfetta, ma ha funzionato per noi per alcuni anni.


2
Non hai spiegato perché.
Robert Harvey,

2
Sì, vorrei anche quella spiegazione.
Aaron Hall,

@AaronHall Consideralo positivo che non capisci la loro scelta.
Leopold Asperger,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.