Avere funzioni di supporto statiche per creare l'argomento del costruttore è una soluzione perfettamente sana, ma queste funzioni sono limitate nelle operazioni che possono eseguire poiché devono produrre esattamente un argomento ciascuna e non possono comunicare tra loro.
Nel caso più generale in cui si desidera adattare un'interfaccia Constructor(A, B, C)
a un'interfaccia più utilizzabile Constructor(X, Y)
, è possibile definire un costruttore di helper privato che accetta%%% e catene per il costruttore esistente. Il costruttore più utilizzabile quindi esegue una catena al costruttore di helper tramite una funzione di supporto statico per creare l'oggetto argomento:
class Constructor {
// constructor you want to wrap
public Constructor(A a, B b, C c) { ... }
// better constructor you are defining
public Constructor(X x, Y y) { this(createArgumentObject(x, y)); }
// helper constructor using an ArgumentObject
private Constructor(ArgumentObject ao) { this(ao.a, ao.b, ao.c); }
// helper to create the argument object
private static ArgumentObject createArgumentObject(X x, Y y) { ... }
private static class ArgumentObject { ... }
}
Nelle lingue che non hanno il concatenamento del costruttore all'interno della stessa classe (come C ++ 03), dovresti definire una sottoclasse intermedia per il costruttore helper.
Tuttavia, questa tecnica è semplicemente una generalizzazione dell'uso delle funzioni statiche negli argomenti del costruttore. Le altre soluzioni che hai proposto hanno vari inconvenienti, motivo per cui vorrei evitarli a meno che non ci sia un buon motivo per preferirle:
-
l'implementazione di buoni costruttori richiede un grande sforzo per pochissimo valore. Se il nuovo costruttore è abbastanza semplice, puoi fare a meno di un costruttore. Supponendo che la classe che si sta eseguendo esegua una validazione solida, si potrebbe rendere pubblico l'argomento object in modo che gli argomenti possano essere passati usando l'idioma ArgumentObject
.
-
l'uso di variabili statiche calcolate in un blocco di inizializzazione statico ha senso per dati veramente statici, ma occorre prestare attenzione per evitare lo stato globale. A meno che l'inizializzazione non sia molto semplice, è necessario utilizzare le funzioni statiche per inizializzare queste variabili affinché l'inizializzazione sia verificabile. Ora, l'unico vantaggio rispetto all'utilizzo diretto dei metodi statici è che i valori vengono calcolati una sola volta e riutilizzati per tutte le inizializzazioni.
Dato che la tua domanda indica che queste inizializzazioni potrebbero essere più complesse, l'uso di blocchi di inizializzazione statici è un grosso problema se la testabilità è importante per te. (Se non lo è, hai più problemi urgenti.)