Ho una classe piena di funzioni di utilità. L'istanza di un'istanza non ha senso semantico, ma voglio ancora chiamarne i metodi. Qual è il modo migliore per affrontarlo? Classe statica? Astratto?
Ho una classe piena di funzioni di utilità. L'istanza di un'istanza non ha senso semantico, ma voglio ancora chiamarne i metodi. Qual è il modo migliore per affrontarlo? Classe statica? Astratto?
Risposte:
Costruttore privato e metodi statici su una classe contrassegnata come finale.
Secondo il grande libro "Effective Java" :
Articolo 4: impone la non-affidabilità con un costruttore privato
- Il tentativo di imporre la non inaffidabilità facendo un abstract di classe non funziona.
- Un costruttore predefinito viene generato solo se una classe non contiene costruttori espliciti, quindi una classe può essere resa non sostanziale includendo un costruttore privato:
// Noninstantiable utility class
public class UtilityClass
{
// Suppress default constructor for noninstantiability
private UtilityClass() {
throw new AssertionError();
}
}
Poiché il costruttore esplicito è privato, è inaccessibile al di fuori della classe. AssertionError non è strettamente necessario, ma fornisce un'assicurazione nel caso in cui il costruttore venga accidentalmente invocato all'interno della classe. Garantisce che la classe non verrà mai istanziata in nessuna circostanza. Questo idioma è leggermente controintuitivo, poiché il costruttore viene fornito espressamente in modo che non possa essere invocato. È quindi consigliabile includere un commento, come mostrato sopra.
Come effetto collaterale, questo linguaggio impedisce anche che la classe venga sottoclassata. Tutti i costruttori devono invocare un costruttore di superclassi, esplicitamente o implicitamente, e una sottoclasse non avrebbe costruttori di superclassi accessibili da invocare.
AssertionError
rispetto ad altre alternative come IllegalStateException
, UnsupportedOperationException
, ecc?
Sembra che tu abbia una classe di utilità simile a java.lang.Math .
L'approccio è di classe finale con costruttore privato e metodi statici.
Ma attenzione a ciò che fa per la testabilità, consiglio di leggere questo articolo
I metodi statici sono Death to Testability
Solo per nuotare a monte, i membri e le classi statici non partecipano a OO e sono quindi malvagi. No, non male, ma seriamente, consiglierei una lezione regolare con un modello singleton per l'accesso. In questo modo, se è necessario ignorare il comportamento in ogni caso lungo la strada, non è un ritocco importante. OO è tuo amico :-)
I miei $ 0,02
commenta gli argomenti del "costruttore privato": dai, gli sviluppatori non sono così stupidi; ma sono pigri. creazione di un oggetto quindi chiamare metodi statici? non succederà.
non perdere troppo tempo per assicurarti che la tua classe non possa essere utilizzata in modo improprio. abbi un po 'di fiducia per i tuoi colleghi. e c'è sempre un modo per abusare della tua classe, indipendentemente da come la proteggi. l'unica cosa che non può essere utilizzata in modo improprio è una cosa completamente inutile.
Non ha senso dichiarare la classe come static
. Dichiara semplicemente i suoi metodi static
e chiamali come normali dal nome della classe, come la classe Math di Java .
Inoltre, anche se non è strettamente necessario rendere privato il costruttore, è una buona idea farlo. Contrassegnare il costruttore come privato impedisce ad altre persone di creare istanze della classe, quindi chiamare metodi statici da tali istanze. (Queste chiamate funzionano esattamente allo stesso modo in Java, sono solo fuorvianti e danneggiano la leggibilità del tuo codice.)
Puoi usare l'annotazione @UtilityClass da lombok https://projectlombok.org/features/experimental/UtilityClass