2009-12-21 17 views
68

Ho una classe costituita da solo di variabili membro statiche e metodi statici. Essenzialmente, serve come classe di utilità generale.È una cattiva pratica per una classe avere solo campi e metodi statici?

È una cattiva pratica per una classe contenere solo variabili membro statiche e metodi statici?

+28

'java.lang .Math' è al 100% metodi statici con un costruttore 'private' (non può essere istanziato). – Asaph

+0

Non sono sicuro se questa domanda è stata posta in questo forum. Ma è una cattiva pratica per una classe avere solo campi statici? Ho visto molte di queste classi e secondo me non rientrano in OOP. – ka3ak

+0

@ ka3ak Le classi con campi statici sono parzialmente indirizzate in alcune risposte a questa domanda. –

risposta

85

No, non penso affatto. È una pratica peggiore avere una classe piena di metodi di istanza che in realtà non dipendono da una particolare istanza. Rendendoli statici dice all'utente esattamente come sono destinati ad essere utilizzati. Inoltre, si evitano instanziazioni inutili in questo modo.

EDIT: Come ripensamento, in generale, ritengo sia opportuno evitare l'uso delle funzionalità del linguaggio "solo perché", o perché si pensa che sia il "modo Java per farlo". Ricordo il mio primo lavoro in cui avevo una classe piena di metodi di utilità statica e uno dei programmatori senior mi disse che non stavo sfruttando appieno la potenza OO di Java rendendo tutti i miei metodi "globali". Non era nella squadra 6 mesi dopo.

+97

ricordami di non intralciarti. – akf

+7

Ha - non proprio quello che intendevo implicare – danben

3

È perfettamente ragionevole. Infatti, in C# è possibile definire una classe con la parola chiave statica appositamente per questo scopo.

13

Suoni ragionevoli.

Nota: le classi che lo fanno hanno spesso un costruttore privato no-arg, in modo tale che il compilatore produca un errore se un programmatore tenta di creare un'istanza della classe statica.

+4

Un costruttore privato predefinito impedisce anche la sottoclassificazione della classe statica. – David

+1

c'è qualche ragione per cui si vuole sottoclasse una classe statica? (non riesco a pensare a uno ... Io non sono un guru del linguaggio) –

+4

Prevenire la sottoclasse in questo caso è un "pro". È possibile che qualcun altro che lavora al tuo progetto possa tentare e sottoclasse accidentalmente la tua classe statica (tramite un errore di battitura o un malinteso). Aggiungendo un costruttore privato predefinito si aggiungono più significati alla classe applicando più rigorosamente il modo in cui può essere utilizzata. – David

2

Si noti inoltre che Java ha introdotto specificatamente l'importazione statica: (http://en.wikipedia.org/wiki/Static_import)

importazione statica è una funzionalità introdotta nel linguaggio di programmazione Java che membri (campi e metodi) definiti in una classe come pubblico statico da utilizzare in codice Java senza specificare la classe in cui è definito il campo. Questa funzione è stata introdotta nella lingua nella versione 5.0.

La funzione fornisce un meccanismo typesafe includere costanti nel codice senza dover riferimento alla classe che originariamente definito il campo . Aiuta anche deprecare il pratica di creare una costante interfaccia : un'interfaccia che solo definisce costanti quindi scrivere una classe attuazione di tale interfaccia, che è ritenuto un uso improprio di interfacce [1].

Il meccanismo può essere usato per fare riferimento singoli membri di una classe:

import static java.lang.Math.PI; 
import static java.lang.Math.pow; 

o tutti i membri statici di una classe:

import static java.lang.Math.*; 
+0

Penso che questo sia un po 'fuori tema per quello che sta chiedendo. L'importazione statica non ha nulla a che fare se una classe ha solo membri statici; funziona se ce ne sono. – danben

+1

Entrambe le buone informazioni e una grande discussione sul perché questo è qualcosa che dobbiamo fare. – Chuck

+0

Scusate, non sono d'accordo - penso che sia un argomento per avere metodi statici, ma non dice nulla di avere classi che non devono essere istanziate. – danben

3

Appena don' essere portato via con esso. Si noti che la classe java.lang.Math riguarda solo le funzioni matematiche.Si potrebbe anche avere una classe StringUtilities che contiene funzioni comuni di gestione delle stringhe che non sono nell'API standard, ad esempio. Ma se la tua classe si chiama Utilità, ad esempio, è un suggerimento che potresti voler dividere.

1

La classe Collections in Java SDK ha solo membri statici.

Quindi, ci si va, fino a quando si dispone di un'adeguata giustificazione - la sua non è una cattiva progettazione

1

metodi di utilità sono spesso collocati in classi con solo metodi statici (. Come StringUtils) costanti globali sono anche messi in la propria classe in modo che possano essere importati dal resto del codice (attributi public final static)

Entrambi gli usi sono abbastanza comuni e hanno costruttori predefiniti privati ​​per impedire che vengano istanziati. Dichiarare la finale di classe impedisce l'errore di provare a sovrascrivere i metodi statici.

Se da static member variables si non significava costanti globali, si potrebbe desiderare di mettere le modalità di accesso a tali variabili in una classe di loro. In tal caso, potresti illustrare cosa fanno queste variabili nel tuo codice?

1

Secondo un'interpretazione rigida di Object Oriented Design, una classe di utilità è qualcosa da evitare.

Il problema è che se si segue un'interpretazione rigida, è necessario forzare la classe in un oggetto di ordinamento per realizzare molte cose.

Anche i progettisti di Java fanno classi di utilità (java.lang.Math viene in mente)

Le opzioni disponibili sono:

double distance = Math.sqrt(x*x + y*y); //using static utility class 

vs:

RootCalculator mySquareRooter = new SquareRootCalculator(); 
mySquareRooter.setValueToRoot(x*x + y*y); 
double distance; 
try{ 
    distance = mySquareRooter.getRoot(); 
} 
catch InvalidParameterException ......yadda yadda yadda.  

Anche se dovessimo evitare il metodo dettagliato, potremmo ancora finire con:

Mathemetician myMathD00d = new Mathemetician() 
double distance = myMathD00d.sqrt(...); 

in questo caso, .sqrt() è ancora statico, quindi quale sarebbe il punto nel creare l'oggetto in primo luogo?

La risposta è, creare classi di utilità quando l'altra opzione sarebbe quella di creare una sorta di classe "Worker" artificiale che non ha o non serve molto per le variabili di istanza.

2

Mentre sono d'accordo con il sentimento che suona come una soluzione ragionevole (come altri hanno già affermato), una cosa che dovresti considerare è, dal punto di vista del design, perché hai una classe solo per "utilità" scopi. Questi funzionali sono veramente generali in tutto il sistema o sono realmente correlati ad alcune classi specifiche di oggetti all'interno della tua architettura.

Finché ci avete pensato, non vedo alcun problema con la vostra soluzione.

17

Fintanto che la classe non ha uno stato interno ed è essenzialmente ciò che è noto come classe foglia (le classi di utilità rientrano in questa categoria), in altre parole è indipendente dalle altre classi. Va bene.

La classe Math è un ottimo esempio.

+0

Hai un bel link/articolo riguardante le classi foglia/utilità? –

9

I metodi statici non mi preoccupano molto (tranne che per i test).

In generale, i membri statici sono una preoccupazione. Ad esempio, cosa succede se la tua app è in cluster? Per quanto riguarda il tempo di avvio, che tipo di inizializzazione sta avvenendo? Per una considerazione di questi problemi e altro, dai un'occhiata a this article di Gilad Bracha.

+2

+1 per distinguere tra funzioni statiche (fine) e stato statico (dubbio) – mikera

0

Non sarei interessato a una classe di utilità contenente metodi statici.

Tuttavia, i membri statici sono essenzialmente dati globali e devono essere evitati. Possono essere accettabili se vengono utilizzati per i risultati di memorizzazione nella cache dei metodi statici e simili, ma se vengono utilizzati come dati "reali" che possono portare a tutti i tipi di problemi, ad esempio dipendenze nascoste e difficoltà nell'impostare i test.

1

Questo collegamento http://java.dzone.com/articles/why-static-bad-and-how-avoid sembra andare contro la maggior parte delle risposte qui. Anche se non contiene variabili membro (cioè nessuno stato), una classe statica può ancora essere una cattiva idea perché non può essere derisa o estesa (sottoclasse), quindi sta vanificando alcuni dei principi di OO

Problemi correlati