Formulare un metodo di costruzione più ragionevole

2

Questa domanda è nel contesto di un'applicazione Android scritta in Java.

Ho questa classe che esegue un'azione specifica e restituisce il risultato di tale azione con un callback implementato nell'attività in cui è stato chiamato. Questa classe dipende dal riferimento di attività corrente. Questo non è un singleton perché questa classe può essere chiamata da diverse attività.

Una soluzione ovvia potrebbe essere qualcosa di simile:

public class MyClass {

    private final Activity mActivity;
    private Callback mCallback;

    public MyClass(Activity activity, Callback callback) {
        mActivity = activity;
        mCallback = callback;
    }

    public void initialize() {
        // do something...
        mCallback.onFinished();
    }

    public interface Callback {
        void onFinished();
    }

}

public class MainActivity implements MyClass.Callback {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new MyClass(this, this).initialize();
    }

    @Override
    public void onFinished() {
        // do something...
    }

}

Funziona e va bene, immagino. Ma davvero non mi piace la riga new MyClass(this, this).initialize(); . Quel new non sembra giusto.

Questo è quando ho trovato una soluzione leggermente diversa e con una piccola variazione sui parametri:

public class MyClass {

    private final Activity mActivity;

    private MyClass(Activity activity) {
        mActivity = activity;
    }

    public static MyClass with(Activity activity) {
        return new MyClass(activity);
    }

    public void initialize(Callback callback) {
        // do something...
        callback.onFinished();
    }

    public interface Callback {
        void onFinished();
    }

}

public class MainActivity implements MyClass.Callback {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyClass.with(this).initialize(this);
    }

    @Override
    public void onFinished() {
        // do something...
    }

}

Esegue esattamente il problema, ma anziché creare esplicitamente un'istanza con la parola chiave new , viene creata implicitamente con il metodo statico with() .

Forse è solo una questione di preferenza ma IMO sembra più naturale dell'uso della parola chiave new . Forse i nomi di with e initialize non sono i migliori, ma cosa ne pensate di questo?

Hai una terza alternativa?

    
posta Ricardo Amaral 09.08.2016 - 12:36
fonte

1 risposta

1

IIRC Josh Bloch in "Effective Java" ha scritto che il secondo approccio è preferibile, ma che a causa delle aspettative degli sviluppatori, i costruttori dovrebbero essere usati in situazioni semplici o qualcosa del genere.

C'è una differenza fondamentale qui che penso valga la pena sottolineare. Le chiamate a un costruttore sono intrinsecamente accoppiate al tipo in questione. Se si crea un metodo factory, l'oggetto reale creato può essere qualsiasi sottotipo della classe. Potresti non averne bisogno, ma offre una flessibilità difficile da replicare in un costruttore raw.

Inoltre, il codice in un costruttore è soggetto a restrizioni che non si applicano al metodo statico. Ad esempio, potrebbe essere necessario chiamare qualcos'altro per determinare cosa passare in un super costruttore o forse quale versione del super costruttore chiamare. Questo tipo di cose sono difficili da impossibile all'interno del costruttore ma sono semplici in un metodo factory.

In una nota a margine, in genere cerco di evitare init o inizializzare i metodi di tipo. Nella mia esperienza, l'inizializzazione di separazione dalla costruzione sta chiedendo problemi. A volte è inevitabile, ma utilizzando metodi di fabbrica o approcci correlati che mantengono l'oggetto in un ambito ristretto finché non è completamente inizializzato, è possibile attenuare completamente questi problemi.

    
risposta data 08.09.2016 - 19:27
fonte

Leggi altre domande sui tag