Domanda

Prendere questa classe scheletro che qualcuno vuole compilare per andare a prendere i flussi RSS su una serie di siti web:

public class RSSStream extends Thread {

    public RSSStream(String rssStreamName,String rssURL,int refreshTime){
        // constructor code goes here
    }
}

Ora, consideriamo che refreshTime deve essere maggiore di zero e che rssURL dovrebbe essere un indirizzo http valida.

Il riflesso evidente è avere qualche valore logico verifica all'interno del costruttore. Tuttavia, una chiamata al costruttore crea un'istanza di un oggetto qualunque cosa accada. Ciò significa che l'oggetto finisce per essere inutile se i valori non permettono di fare il suo lavoro. Questo significa anche che l'oggetto deve essere infine scaricata o riutilizzata.

Quindi, ecco un paio di domande sul tema:

  • Perché alcune classi impongono un metodo getInstance () accoppiato con quello che è probabilmente un costruttore privato? Se ricordo bene, un esempio potrebbe essere GregorianCalendar.
  • In quali casi useresti questo stesso approccio?
  • Nella maggior parte dei casi avete la logica controllo nel costruttore?
  • Se è così, non si applica questo o no alle classi stile Entità utilizzati nel contesto di persistenza di un modello di dominio?

Tutte le vostre risposte sono i benvenuti. Sarà interessante per avere una chiara visione della pratica più comune è.

È stato utile?

Soluzione

Alcune delle cose più comuni:

  • Se si utilizza FactoryMethod per la costruzione di oggetti complessi sarete in genere avere un costruttore privato e richiedono esemplificazione attraverso la fabbrica. Questo supporta la commutazione strategie di costruzione con la fabbrica.

  • più chiaro per me sarebbe lanciare un costume (e, si spera informativa) Eccezione nel costruttore se istanziazione non può accadere::

    public class Persona {

        public Person(Integer id, String name) throws InvalidPersonException
             if (name==null) throw new InvalidPersonException("You cant have a person without a name");
             ...
    
  • Questo rischia di creare un disastro negli oggetti entità di persistenza, soprattutto perché si desidera che questi oggetti siano privi di logica, e perché il quadro dovrebbe gestire questo per voi - per esempio se si dispone di un fagiolo che contiene (id, nome) in ibernazione e cercare di persistere in una tabella con il nome richiesto di essere non nullo, l'errore del db lancia o dalla configurazione dovrebbe essere sufficiente.

Altri suggerimenti

Se il valore controllo è necessario fare può lasciare l'istanza dell'oggetto in uno stato corrotto, allora si dovrebbe prendere in considerazione la creazione di una fabbrica per generare le istanze. Questo vi permetterà di generare un'eccezione nel caso in cui gli argomenti che vengono passati non sono validi.

Se, tuttavia, l'oggetto può essere "fissato" nel costruttore con valori di default nel caso in cui la convalida non riesce quindi utilizzare i valori di default per fornire al chiamante con un oggetto che è inutile, ma non corrotto.

Se il vostro genera un'eccezione, il riferimento all'oggetto non viene restituito in modo l'oggetto può essere immediatamente garbage collection. Quindi non sta sprecando la memoria. Credo che questo sia il posto giusto per fare la vostra convalida ogni volta che si sta costruendo oggetti, oggetti in particolare immutabili.

getInstance () è un metodo factory che restituisce un'istanza di una sottoclasse. È possibile utilizzare questo quando si restituisce una sottoclasse diversa a seconda delle circostanze. Ad esempio, Calendar.getInstance () restituisce un GregorianCalendar nel mio locale, ma può restituire un'implementazione diversa se le mie impostazioni locali sono diverse.

Per vari modelli per la creazione di oggetti, controllare http://en.wikipedia.org/wiki/ Creational_pattern

Spero che questo aiuti

  • ho visto in primo luogo e ha utilizzato un getInstance() statica e costruttore privato solo per l'uso del pattern Singleton. Tuttavia, classe astratta Calendar di Java utilizza questo metodo non per un Singleton, ma per istanziare un'implementazione di default (gregoriano) con un fuso orario e localizzazione predefinita. Forse questo è fatto perché Calendar è astratta e non può essere istanziato. GregorianCalendar ha effettivamente costruttori pubblici.
  • Nella maggior parte dei casi, avevo appena un costruttore pubblico senza argomenti e metodi setter, e non metto la logica di controllo e l'eccezione lancio nei metodi setter. Mi capita spesso di usare l'iniezione di dipendenza di primavera, e la @Required annotazione permette di avere il contenitore un'eccezione se tutti gli attributi richiesti non sono impostati.
  • Non applicare questo tipo di logica in oggetti entità, cerco di tenere ogni logica di loro per semplicità, e li rigorosamente POJO fare.

In questo caso particolare vorrei solo fare la convalida degli argomenti nel costruttore e gettare un IllegalArgumentException con il messaggio di errore descrittivo. L'oggetto non sarebbe stato creato e il codice chiamante avrebbe dovuto essere riparato.

È possibile farlo in un metodo getInstance () troppo. Uno dei motivi per utilizzare un getInstance () è se le istanze sono molto condivisibili, per ridurre il numero di oggetti creati. Per esempio se si può avere più oggetti RSSStream con lo stesso URL, si potrebbe mettere su una getInstance () per condividere tali istanze. (Premesso che le istanze sono immutabili.)

C'è anche il builder. Avresti una classe interna nidificato chiamato RSSStream.Builder e dire cose come:

RSSStream rss = new RSSStream.Builder.build(url)
                                     .name("stack overflow")
                                     .refreshTime(2)
                                     .build();

Questo modello rende il codice del client più auto-descrittivo e assicura anche di non costruire un RSSStream in uno stato non valido (i metodi del costruttore gettano IllegalArgumentException). Un costruttore è abbastanza flessibile per sostituire tutti i costruttori pubblici.

Sono generalmente usato IllegalArgumentException, gettandolo dal costruttore, o un metodo di validazione (a fattore il controllo degli errori di codice di più costruttori). Ho iniziato a utilizzare il metodo del costruttore per i miei più importanti API pubbliche e piace molto.

Si può certamente utilizzare queste tecniche nelle classi modello di dominio.

Costruttori che hanno bisogno di convalidare le loro argomentazioni in genere buttare un IllegalArgumentException se la convalida non riesce. Quando un costruttore genera un'eccezione, nessun oggetto "a metà strada inizializzato" è lasciata di cui preoccuparsi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top