Implementazione e riflessione fluide dell'interfaccia. Argomento di studio

5

Spero di aver scelto il gruppo giusto per questa domanda ...

Ho questo piccolo quadro che voglio implementare e vorrei avere un'opinione in merito. In particolare, sono più preoccupato per la concisione e lo stile della soluzione. Il mio schizzo di classe ha questo aspetto:

public interface Builder<T> {

    T build();
}

public interface RootObject {


    public static abstract class MutableBuilder<T> implements Builder<T> {

        protected MutableBuilder() { }

        protected abstract void setA(A a);

        protected abstract void setB(B b);

        protected abstract void setC(C c);

        protected abstract void setD(D d);
    }
}

L'obiettivo è avere un Builder che restituisca un'istanza di oggetti (si spera) immutabili. L'intera implementazione è lasciata al codice client, ma voglio comunque dare l'imprinting dell'interfaccia fluente di Java efficace.

Se fosse solo per questo, non sarei perplesso. Il problema si verifica quando aggiungo i requisiti:

  • il framework deve riflettere in modo riflessivo attraverso un'implementazione generica RootObject per trovare se la classe interna statica MutableBuilder è stata implementata.
  • se trovato, il framework istanzia uno o più MutableBuilder dinamicamente (questo è il motivo per cui ho una classe astratta con un costruttore e la restituisco al codice client.

Il semplice parlare di riflessione mi fa chiedere se sto facendo la cosa giusta. Sembra una soluzione ragionevole per me (ovviamente).

    
posta Andrea Richiardi 21.03.2013 - 04:38
fonte

1 risposta

3

Se possibile, diventa naturale

Voglio iniziare dicendo che Java ha tecniche di creazione di oggetti incorporate ("naturali"). Forzare i tuoi clienti a dichiarare tipi specifici per la creazione di oggetti senza una ragione specifica farà sì che il tuo framework sia lontano da "facile da usare".

Evita l'introspezione se possibile.

Stai abusando del termine (accettato) " builder ".

Un builder dovrebbe essere usato solo se un tipo ha parametri opzionali. Non tutti i tipi hanno questo, quindi richiedere un costruttore per ogni oggetto è un abuso del modello.

Se stai usando il builder per disaccoppiare un'implementazione, il modello corretto da implementare sarebbe il schema dei metodi di fabbrica

Preferisci una fabbrica sulla tua soluzione attuale

Nei commenti del tuo post, hai citato il tuo framework ora richiede al cliente di passare in un costruttore. Anche se è bello che tu abbia trovato una soluzione, sembra che ci sia un problema più grande con il tuo attuale design.

I builder non dovrebbero definire le proprietà richieste , poiché il client non è obbligato ad eseguire i comportamenti da esso forniti. Questo trasforma il requisito in un'opzione (criticamente) raccomandata, ed è per questo che i costruttori utilizzano ancora costruttori di classi. Il tuo design abusa attualmente del pattern, e dal suono del comportamento che stai cercando di ottenere, una fabbrica sarebbe più adatta.

    
risposta data 01.11.2016 - 04:01
fonte

Leggi altre domande sui tag