Ho un metodo factory Java con una matrice varargs di Object
s alla fine. La matrice può contenere qualsiasi combinazione di String
s e ScaledJpeg
s. La teoria è che una cella di tabella HTML può contenere un numero qualsiasi di nodi di testo o <image>
nodi e verrà allineata a linee come se fossero solo parole a forma di divertente.
// constructor
public Cell(TextStyle ts, float w, CellStyle cs, Object... r) {
if (w < 0) {
throw new IllegalArgumentException("A cell cannot have a negative width");
}
if (r != null) {
for (Object o : r) {
if ( (o != null) &&
!(o instanceof String) &&
!(o instanceof ScaledJpeg) ) {
throw new IllegalArgumentException(INVALID_ROW_TYPE_STR);
}
}
}
textStyle = ts; width = w; cellStyle = cs; rows = r;
avgCharsForWidth = (int) ((width * 1220) / textStyle.avgCharWidth());
}
In Scala, potrei usare un elenco di Either[String,ScaledJpeg]
. Ma un giorno probabilmente farò in modo che questo metodo consenta qualcos'altro, diciamo un altro% co_de annidato, ma così facendo si romperebbe il codice esistente che si aspettava solo due possibili tipi. Almeno in questo modo, le modifiche future non infrangeranno il codice esistente.
La soluzione corrente funziona, consente l'espansione ed è relativamente facile da usare, tranne che sconfigge la sicurezza del tipo e può solo generare un'eccezione in fase di esecuzione se qualcuno passa qualcosa di imprevisto come vararg. Ad esempio, ho appena dimenticato di aggiungere Cell
a toString()
e si è verificato durante il runtime. Quindi già questa è una terza classe da considerare (Poiché StringBuilder
è definito su ogni oggetto, non voglio chiamarlo su ciò che viene passato perché farlo per la maggior parte dei tipi di oggetti sarebbe un errore molto più in basso nel codice che viola il comportamento a prova di errore di questo esempio).
toString()
non può implementare nuove interfacce e probabilmente è una buona cosa. Anche se potessi fare una classe wrapper, tutto ciò che riguarda il modo in cui il testo e le immagini sono trattati da questa classe è completamente diverso tranne che sono allineati in linea come sarebbero in HTML (o in una Word doc).
Mentre scrivo questo, mi viene in mente che dovrei probabilmente usare un pattern Builder, creare una classe java.lang.String
che ha metodi CellBuilder
e addText()
che eliminano il costruttore varargs. Ciò incapsulerebbe l'Elenco sottostante in modo che l'utente dell'API ottenga la sicurezza del tipo al 100% in fase di compilazione. Ma per curiosità, lo sto ancora postando nel caso ci siano altre soluzioni creative e forse migliori là fuori.