Tutte le classi hanno un costruttore predefinito come parte di una buona convenzione di codifica

5

Dai testi che ho letto fino ad ora, le convenzioni parlano dell'organizzazione di constructors , a partire da default , se ce ne sono. Mi chiedo, se tutte le classi avessero comunque una default constructor . Ciò aiuterà almeno a creare una semplice istanza di class al volo, senza dover utilizzare un parameterized constructor , che a sua volta potrebbe richiedere imports aggiuntivo per un tipo di parametro specifico.

    
posta Shamim Hafiz 14.06.2013 - 19:33
fonte

6 risposte

10

In generale, dovresti avere costruttori per le classi che prendono abbastanza parametri per inizializzare correttamente l'oggetto che si sta creando in uno stato valido. Se la tua classe è in grado di fornire impostazioni predefinite sane per tutti i campi che comprendono uno stato valido per gli oggetti di quella classe, è probabile che un costruttore predefinito sia una buona idea.

Inoltre, alcune librerie richiedono l'esistenza di un costruttore predefinito per determinate operazioni. Ad esempio, le librerie in Java utilizzate per la deserializzazione di json / xml richiedono spesso un costruttore predefinito da richiamare tramite riflessione poiché quelle librerie tenteranno di valutare tutto in fase di esecuzione e non potranno sapere in anticipo quali sono i costruttori disponibili da utilizzare, quindi si aspettano un costruttore predefinito. In casi come questi se un tool di costruzione predefinito è richiesto da tooling, ma non dovrebbe essere chiamato da qualsiasi cosa tu controlli o utenti della tua API, è meglio usare l'idioma comune della tua lingua per contrassegnare il costruttore come privato (es. Accesso privato nelle tipiche lingue tipizzate staticamente).

    
risposta data 14.06.2013 - 19:44
fonte
7

Ci sono due casi in cui il costruttore predefinito ha poco senso:

  1. Affidamento di una classe sul suo campo o proprietà.

    Immagina una serie di classi che caricano i dati statistici dal database e li visualizzano in un grafico. Una delle classi, DataTransform , normalizza i dati dal database per poter essere utilizzati in un grafico. Questa classe utilizza un IDataProvider che alimenta DataTransform con dati non elaborati.

    Per essere testabili e interoperabili, hai quattro classi che implementano IDataProvider : quella per Oracle, quella per Microsoft SQL Server, quella che carica i dati direttamente da XML e infine la simulazione da utilizzare nei test unitari.

    Avere un costruttore predefinito ti costringerebbe a:

    • Controlla quasi tutti i metodi di DataTransform che il campo IDataProvider dataProvider è stato inizializzato,

    • Aspettatevi che chiunque usi la classe chiamerà il costruttore parametrizzato o chiamerà il costruttore predefinito e quindi imposterà il fornitore di dati attraverso una proprietà o un metodo addizionale.

    Questo indica un problema serio nella progettazione. Lanciare il costruttore predefinito e avere esclusivamente il costruttore che prende il fornitore di dati come parametro rende la classe più intuitiva da usare e il suo codice più semplice.

  2. Oggetti immutabili per i quali le impostazioni predefinite non hanno senso.

    Immagina un% co_de immutabile che ha come proprietà Person , FirstName e LastName . Mentre il nome e il cognome possono essere predefiniti su una stringa vuota (o null, se la lingua autorizza stringhe null), quale sarebbe la data di nascita? La data minima autorizzata? Perché vorresti mai una persona immutabile senza nome e nata il 1 ° gennaio st , anno 1?

    Si noti che l'immutabilità da sola non significa che non ci dovrebbe essere alcun costruttore predefinito. Ad esempio, ha senso avere un costruttore predefinito per BirthDate , risultante in Point ; un altro modo è avere una costante statica Point(x = 0, y = 0) . Un altro esempio: ha perfettamente senso avere un costruttore predefinito per un Point.Zero immutabile (una stringa nulla o vuota).

risposta data 14.06.2013 - 20:02
fonte
5

La ragione per cui alcune classi scelgono di avere solo un costruttore complesso è spesso che non possono lavorare in modo utile senza conoscere le informazioni di base su un'istanza. Essere in grado di creare un'istanza banale non è vantaggioso in questo caso, anzi, probabilmente è uno svantaggio, perché tutti i metodi devono essere in grado di gestire un oggetto che non ha dati cruciali! Disabilitando questo, è spesso possibile stabilire invarianti per una classe che consente di risparmiare molto tempo di codifica e sforzi di runtime.

Una regola generale su quali costruttori "dovresti" o non dovresti avere ha poco peso contro tali considerazioni specifiche di classe. In pratica, l'unica ragione valida per far rispettare un costruttore banale che abbia mai visto è se si consegnano gli oggetti a un framework che ne richiede uno. Anche allora probabilmente renderò privato il costruttore se riesco a farla franca.

    
risposta data 14.06.2013 - 19:45
fonte
3

Assolutamente no. Il valore predefinito è dovuto se la classe può essere costruita in modo ragionevole senza alcuna informazione proveniente dall'esterno. (Se limiti la domanda a quel sottoinsieme, la risposta diventa yes).

Altrimenti avere un ctor predefinito impone l'inizializzazione a due stadi con tutti gli inconvenienti che attira. Lo abbiamo scelto solo per ragioni estremamente buone.

    
risposta data 14.06.2013 - 20:05
fonte
2

Dipende dallo stile di codifica e dai modelli implementati. Con Dependency Injection (DI) ti troverai spesso con un costruttore predefinito solo quando ne hai effettivamente bisogno, sia per la serializzazione XML che per qualsiasi altra cosa. Essere polarizzato con DI, tenderei a dire di no, non è necessario un costruttore predefinito, poiché l'unico lavoro che viene svolto in un costruttore è l'iniezione delle dipendenze della classe: i costruttori diventano una documentazione statica delle dipendenze di un tipo .

    
risposta data 14.06.2013 - 19:50
fonte
0

Non mi piacciono i consigli tutto o niente. Su quei termini, direi di no.

Prendi in considerazione ogni pratica caso per caso. Nessun proiettile d'argento.

Crea solo un costruttore predefinito se ne hai bisogno. YAGNI è una convenzione di codifica migliore.

    
risposta data 15.06.2013 - 03:17
fonte