Funzione di utilità o funzione di supporto in classe?

0

Sto lavorando con php e usiamo enum creando una classe Abstract che deride il comportamento enum - ma la mia domanda è cross-lingue.

Dove tutto l'helper funziona come toString , getEnumTypes , checkValidValue , ecc ... dovrebbe essere, in una classe di utilità dedicata: EnumUtil o in AbstractEnum se stesso (tutte le enumerazioni si estendono AbstractEnum quindi tutte le enum hanno quelle funzioni)

E se la risposta è nella AbstractEnum stessa in quali casi dovrei creare una classe di utilità?

P.S: Questa è una domanda di carattere generale, ma l'ho focalizzata con un esempio di vita reale.

    
posta Michael 19.07.2017 - 11:12
fonte

3 risposte

3

Se le funzioni sono significative per tutte le enumerazioni, usa la classe base.

"Le classi di utilità" in generale dovrebbero essere evitate. O per dirla in altro modo, se puoi solo pensare al nome FooUtility per una classe, la funzionalità probabilmente appartiene a Foo piuttosto che a una classe separata.

Modifica: Ovviamente ciò dipende dalla definizione di "classe di utilità", poiché non è un termine con una definizione assoluta. Ma se l'unico scopo di una classe è di fornire funzioni di utilità per operazioni su un'altra classe, come nel tuo esempio, allora le funzioni appartengono a quella classe. Solo una giustificazione a cui posso pensare per una classe separata sono le funzioni di utilità per una classe sigillata.

    
risposta data 19.07.2017 - 11:38
fonte
0

Tutti i metodi che hanno senso per essere applicati direttamente a un valore enum dovrebbero essere in AbstractEnum come toString . Metodi statici come il recupero di un valore da una stringa ( valueOf in Java) possono essere inseriti in una classe helper o collocati direttamente nella classe enum derivata (anche se eviterei di inserirlo in AbstractEnum per motivi di semplicità).

Idealmente, il costruttore di AbstractEnum e tutte le classi derivate sarebbero protetti e istanziati solo dalla classe stessa in modo statico, così che non c'è possibilità di controllare l'uguaglianza tra istanze separate dello stesso "valore enum".

Tuttavia, come regola generale, devi posizionare i metodi in AbstractEnum solo se ha senso chiamare tale metodo su un'istanza specifica.

    
risposta data 19.07.2017 - 12:24
fonte
-1

Non sono d'accordo con la saggezza generalmente accettata che le classi di utilità dovrebbero essere evitate. Usando Java qui come esempio, ma sono sicuro che l'idea si applica anche ad altre lingue.

Considera, ad esempio, un tipo di dati di cui hai bisogno sia delle varianti mutabili (per le prestazioni) che immutabili (per hash table, set, altri tipi di problemi di correttezza, ecc.): un numero complesso. Quindi, hai Complex (immutabile) e ComplexBuffer (mutabile). Ora sarebbe sciocco scrivere quattro versioni della sottrazione di sottrazione ( Complex - Complex , ComplexBuffer - Complex , Complex - ComplexBuffer , ComplexBuffer - ComplexBuffer ), quindi vuoi creare un'interfaccia comune ComplexNumber condivisa da Complex e ComplexBuffer . L'interfaccia ComplexNumber ha metodi getReal() e getImag() .

Ora, per sottrarre due oggetti di implementazione di ComplexNumber , definirai una classe ComplexUtils e un metodo statico public static Complex sub(ComplexNumber, ComplexNumber) . Quindi, ecco qui: un problema in cui la soluzione migliore è effettivamente utilizzare una classe di utilità. Ovviamente, per le prestazioni avrai anche ComplexBuffer.subInPlace(ComplexNumber) che non crea assolutamente nuovi oggetti.

Quindi, non seguire ciecamente il consiglio che le classi di utilità dovrebbero essere evitate. Come ha detto John Carmack:

Sometimes, the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function.
    
risposta data 19.07.2017 - 15:37
fonte

Leggi altre domande sui tag