UPD
Nelle convenzioni di codifica aggiornati, c'è un section on this topic:
funzioni di fabbrica
Se si dichiara una funzione di fabbrica per una classe, evitare di dare lo stesso nome come la classe stessa. Preferisci usare un nome distinto per chiarire perché il comportamento della funzione di fabbrica è speciale. Solo se non c'è davvero una semantica speciale, puoi usare lo stesso nome della classe.
Esempio:
class Point(val x: Double, val y: Double) {
companion object {
fun fromPolar(angle: Double, radius: Double) = Point(...)
}
}
La motivazione che ho descritto qui di seguito, però, sembra tenere ancora.
Come detto nella documentazione sulla naming style:
In caso di difetto di dubbio al Java convenzioni di codifica, quali:
- metodi e le proprietà iniziano con minuscole
Una ragione forte t o evitare di nominare una funzione stessa a una classe è che si potrebbe confondere uno sviluppatore che lo userà più tardi, perché, contrariamente alle loro aspettative:
- la funzione non sarà disponibile per la chiamata Super costruttore (se la classe è
open
)
- non sarà visibile come un costruttore attraverso la riflessione
- non sarà utilizzabile come costruttore nel codice Java (
new HashSet(n, it -> "Element " + it)
è un errore)
- se si desidera cambiare l'implementazione più tardi e restituire invece un'istanza di sottoclasse, sarà ancora più confuso il fatto che
HashSet(n) { "Element $it" }
wil l costrutto non un HashSet
ma, per esempio, un LinkedHashSet
È meglio mostrare esplicitamente che è una funzione di fabbrica, non un costruttore, per evitare questa confusione.
Anche la denominazione di una funzione identica a una classe viene generalmente evitata anche in stdlib.Dato SomeClass
, in stdlib uno stile di denominazione preferito per le funzioni di fabbrica è someClassOf
, someClassBy
o qualsiasi altra cosa spieghi la semantica della funzione migliore. Gli esempi:
generateSequence { ... }
e sequenceOf(...)
lazy { ... }
e lazyOf(...)
compareBy { ... }
listOf(...)
, setOf(...)
, mapOf(...)
Quindi, si dovrebbe sicuramente forte motivo per avere una funzione di imitare un costruttore.
Al contrario, il nome di una funzione potrebbe indicare all'utente (anche a tutto) il suo utilizzo.
davvero? Quindi ora i costruttori secondari sono migliori delle funzioni di fabbrica? Penso che abbiamo bisogno di un parere ufficiale (nei documenti) – voddan
@voddan, la domanda e la risposta non riguardano i costruttori secondari, si tratta di avere una funzione che imita un costruttore. Per quanto riguarda i costruttori secondari, essi non sono utili quando una funzione deve restituire un'istanza di sottoclasse con un'implementazione diversa. Altrimenti, sembrano adattarsi meglio delle funzioni di fabbrica (riflessione, chiamata super ctor, interopzione Java). – hotkey
beh, l'unica proposta di funzioni denominate come classi è il factoring di quelle classi senza inondare il codice di classe. L'alternativa è costruttori secondari, ed è una specie di implicita nella tua risposta. – voddan