2009-05-16 26 views
30

Qual è la differenza in Java tra una classe di utilità (una classe con metodi statici) e una classe di servizio (una classe con metodi pubblici che fornisce un "servizio"). Ad esempio, si può sostenere che un oggetto crittografico (che fornisce metodi per crittografare, decifrare, hash o ottenere un valore salt) è un fornitore di servizi, ma molti raggruppano questa funzionalità in una classe di utilità con metodi statici, come CryptoUtil.encrypt (.. .). Sto cercando di capire da che parte segue meglio "design". Pensieri?Java Utility Class vs. Service

risposta

19

diversi comportamenti possono essere ottenuti utilizzando diversi oggetti del servizio. I metodi statici in una classe di utilità non possono essere scambiati. Questo è estremamente utile per testare, cambiare implementazioni e altri scopi.

Ad esempio, si parla di un CryptoUtil con un metodo encrypt. Sarebbe estremamente utile avere oggetti diversi che potrebbero supportare diverse strategie di crittografia, diversi destinatari di messaggi, ecc.

7

La differenza è che le classi di servizio potrebbero avere lo stato. E per stato intendo lo stato di conversazione. Si consideri un sistema di ordinamento teorico.

interface OrderSystem { 
    void login(String username, String password); 
    List<Item> search(String criteria); 
    void order(Item item); 
    void order(Item item, int quantity); 
    void update(Item item, int quantity); 
    void remove(Item item); 
    void checkout(); 
    Map<Item, Integer> getCart(); 
    void logout(); 
} 

Una cosa del genere potrebbe essere fatto con i fagioli di sessione stateful (come un esempio), anche se in quel caso l'autenticazione probabilmente essere coperto meccanismi EJB più tradizionali.

Il punto qui è che vi è uno stato di conversazione in quanto i risultati di una chiamata influiscono sulle chiamate successive. È possibile visualizzare i metodi statici come una serie di semplici servizi stateless eseguiti localmente.

Un servizio ha un significato molto più ampio che include, ma non è limitato a, essere:

  • stateful;
  • remoto; e
  • dipendente dall'implementazione (cioè tramite un'interfaccia).

Le migliori pratiche penso sia semplicemente utilizzare metodi statici come metodi di convenienza (soprattutto data la mancanza di metodi di estensione di Java). I servizi sono molto più ricchi di così.

+1

Una variabile statica conserva lo stato per una classe statica. Non che io stia incoraggiando le classi statiche - sto solo dicendo ... –

+2

La maggior parte delle classi che ho visto con stato statico sono esempi di quello che io chiamo il modello "Vorrei essere un singleton". –

+0

Lo stato statico in una classe statica è uno dei modi migliori che conosco (se non il migliore) per entrare nel fantastico mondo dei problemi di concorrenza. Dì solo ... –

0

Penso che non ci siano regole dure e veloci.

In genere utilizzo metodi statici per funzionalità che richiedono pochi parametri e possono essere eseguiti in una singola chiamata di metodo. Esempio:

  • calcolare un valore hash per una stringa
  • convertire una data di rappresentazione standard

Se una funzionalità richiede molti parametri, e se ci sono diversi risultati correlate venga creato, quindi è più pratico per avere una classe in grado di accettare i parametri condivisi nel suo costruttore, con diversi metodi che eseguono l'azione reale.

Esempio tipico: una connessione al database, che prima connessione, quindi utilizzare per fare una query, quindi utilizzare per ottenere il risultato ...

0

Ho risposto a questa domanda qui da qualche parte prima, ma quello che ho trovato è stato che è stato molto facile cambiare il comportamento di un servizio - rifattarlo in più servizi - dove ci vuole un refactoring piuttosto significativo se si utilizza un classe statica.

Se questa è l'unica differenza (e credo che lo sia), non ha mai senso utilizzare classi statiche.

Ogni volta che qualcuno dice "Non ci sarà mai più di 1 di questi", codice per n di essi.

3

Non è possibile sovrascrivere il metodo statico, che può essere un grosso problema nel caso in cui si desideri implementare il servizio in due modi diversi e passare da uno all'altro. Per questo motivo, limiterei l'uso di classi di utilità statiche a cose semplici che "mai" (per un valore sufficientemente lungo di "mai" :)) devono essere eseguite in più di un modo.