Gli array sono strutture dati idonee per i costruttori?

3

La mia domanda proviene da quest'altra domanda .

La prima volta che ho letto la domanda, ho capito (forse logicamente) che l'OP chiedeva un modo diverso per inizializzare l'oggetto in modo tale da consentirgli di estendere e semplificare la manutenzione. Quindi la mia risposta.

Tuttavia, alcuni commenti sembrano essere d'accordo con il passare un array in quanto un singolo argomento sarebbe ancora più semplice.

Di solito non trasformiamo una funzione con i parametri # denominati in una funzione con una singola matrice di # posizioni.

public Message(String id, String a, String b){...}

public Message(String[] arguments){...}
public Message(String... arguments){...}

Girare # parametri con nome (tutti dello stesso tipo) in un array è qualcosa che ho fatto nei miei primi giorni come programmatore. Allora, mi resi conto di quanto fossero fragili. Ad esempio, queste strutture sono molto sensibili ai cambiamenti. L'ordine degli elementi all'interno dell'array e la lunghezza dell'array sono importanti, perché mappiamo attributi, campi o variabili in posizioni all'interno dell'array.

La seguente domanda è d'accordo con me. L'unica differenza apparente è che la domanda precedente, la funzione è un costruttore e nell'ultimo è un metodo.

Quindi, osservando entrambe le domande collegate qui, vedo come da una parte stiamo suggerendo di utilizzare gli array nel modo in cui ho commentato e dall'altra parte, siamo scoraggianti dal fare la stessa pratica.

La mia domanda si riduce a, dal punto di vista OOP, Gli array (come strutture dati) sono adatti per i costruttori ma i metodi inadatti?

Se sì. Perché? Applichiamo diverse "regole" per definire le firme del costruttore e del metodo? In definitiva, entrambe sono funzioni.

Se no. Quando è appropriato usare l'uno o l'altro?

Per me, entrambi i casi mancano di manutenibilità, leggibilità e scalabilità.

    
posta Laiv 21.07.2017 - 23:01
fonte

3 risposte

6

Non ci sono differenze nell'idoneità degli array [1] come argomenti di funzioni o di costruzione. La vera domanda è se un array è un modello corretto per il tipo di dati che hai. Nel tuo esempio in cui hai un messaggio in 2 parti con un ID, trasformando (pseudo codice)

Message(String id, String a, String b)

a

Message(String[3] message)

è sbagliato perché una matrice è la struttura dati errata per quel tipo di dati. Non hai una lista di tre testi. Quello che hai sono tre pezzi di dati che comprendono una singola entità strutturata. Quindi anche i tre argomenti separati sono altamente discutibili perché non riescono a esprimere che tutti appartengono insieme. Almeno usa qualcosa del genere:

struct MessageData {
    String id;
    String a;
    String b;
}

Message(MessageData message)

Tuttavia, non è nemmeno la struttura dati ideale. id dovrebbe essere davvero di un suo tipo distinto che forse contiene una stringa all'interno. Perché?

  • È un identificatore, non un testo. Quindi non dovrebbe essere una stringa.
  • Disponiamo di dati testuali che rappresentano due concetti diversi: "identificatore" e "testo del payload". (Almeno questo è il modo in cui ho scelto di interpretare a e b per mancanza di informazioni più specifiche sul tipo di messaggio.) I diversi concetti dovrebbero essere modellati come tipi diversi.

Ciò a cui tutto questo si riduce è: Utilizza il sistema di tipi alla sua massima estensione per rendere le tue strutture dati il più espressive possibile. Dopotutto, ecco perché abbiamo i sistemi di tipi in primo luogo.

[1]: sto usando "array" in senso lato qui - come in un contenitore per una sequenza di valori

    
risposta data 22.07.2017 - 11:24
fonte
8

È possibile utilizzare in modo assoluto gli array come strutture di dati e passarli a costruttori e metodi. Lasciatemi proporre alcuni esempi:

  • Un'applicazione di adattamento della curva. Il modello complesso viene suddiviso in una serie di numeri in virgola mobile a precisione doppia che rappresentano i parametri di adattamento. La funzione che calcola l'errore di adattamento includerà questa serie di numeri in virgola mobile a precisione doppia oltre a un riferimento al modello complesso. Il vantaggio è che il codice di adattamento di per sé non ha bisogno di conoscere il modello complesso, ha solo bisogno di conoscere i parametri di montaggio N. Quindi, puoi sviluppare il codice di adattamento indipendentemente dal tuo codice di simulazione.
  • Grafici a linee di disegno. Fornirai alla libreria del grafico a linee due array di numeri in virgola mobile a precisione doppia: uno che contiene i valori X e altro che contiene i valori Y. Se usi Java, il vantaggio è che la matrice è molto più veloce e ha bisogno di meno garbage collection di alcuni astratti List di Pair<Double, Double> objects.
  • Argomenti della riga di comando. La funzione main prende una matrice di oggetti String .
  • Simulazione di curve monodimensionali per il montaggio. La funzione prende un punto dati di coordinate X insieme a un modello complesso e calcola la quantità di interesse per ciascun punto di dati.

Sono sicuro che ci sono molti altri esempi. Ho appena scelto gli esempi rilevanti per l'applicazione che sto attualmente sviluppando.

    
risposta data 21.07.2017 - 23:14
fonte
1

La domanda collegata sta cercando un modo per non passare esplicitamente in tutte le proprietà di un oggetto che non usa setter.

Il modo normale di avere qualche altra classe di impostazioni o struct con i valori denominati e di passarli non li aiuta perché quella classe avrebbe essenzialmente lo stesso problema.

Quindi qualcuno suggerisce di passare in un array. Ma non come un modo ottimale di costruire, poiché ovviamente perdi i nomi dei parametri. Proprio come una soluzione pratica al loro dilemma irrisolvibile.

    
risposta data 22.07.2017 - 11:51
fonte

Leggi altre domande sui tag