Un singolo oggetto è preferibile su più variabili?

8

È stato abbastanza difficile inserire ciò che intendevo in un titolo, ma è facile da inserire nel codice.

C ++

È questo

int offset_x = 10;
int offset_y = 40;
...
element.move(offset_x, offset_y);

Preferire questo?

Vector<int> offset(10, 40);
...
element.move(offset.x, offset.y);

(nota che Vector non è come std::vector , è un vettore 2D. Questa classe ha molti metodi che non ho bisogno qui, come normalize() e scale() . Dovrei avere un% di base più co_de classe per questo?)

JavaScript

È questo

var offsetX = 10;
var offsetY = 40;
...
element.move(offsetX, offsetY);

Preferire questo?

var offset = {x: 10, y: 40};
...
element.move(offset.x, offset.y);
    
posta futlib 06.03.2013 - 07:22
fonte

3 risposte

12

Ho "ereditato" un sacco di codice legacy usando la tua prima variante, e ho anche scritto un sacco di codice da solo usando Point2D e Point3D classi (essenzialmente lo stesso di Vector<int> ). La prima variante porta sempre alle funzioni con troppi parametri e troppi costrutti ripetuti in cui l'aggiunta vettoriale semplice o la moltiplicazione scalare viene ripetuta ancora e ancora in diverse righe di codice.

L'utilizzo di classi di punti o vettori 2D, tuttavia, soprattutto quando si ha la necessità di molte operazioni con vettori, rende il codice molto più pulito, conciso, meglio leggibile e manutenibile. Se dovresti usare un Vector<int> esistente, o scrivere la tua classe Point , è impossibile dirlo senza sapere di più sui dettagli del tuo codice, ma in generale, se una classe esistente ne soffre, perché non riutilizzarla? I metodi aggiuntivi che non ti servono tipici non fanno male. Ma non usare qualsiasi classe 2D punto / vettore è quasi sempre una decisione sbagliata. E nel tuo esempio precedente: se hai influenza sulla funzione element.move , IMHO stai meglio progettarlo in un modo che puoi chiamare element.move(offset) invece di element.move(offset_x, offset_y) .

Ad esempio, supponiamo di aver bisogno di un array di coordinate di punti e di utilizzare std::vector . Nel primo caso, avrai bisogno di due std::vector<int> variabili, devi assicurarti che quei due vettori siano "in sincronia" l'uno con l'altro, e che tutti aggiungano nuovi elementi, trovando elementi esistenti, passando attorno a questi elementi servono due righe di codice invece di una quando invece hai scelto di usare std::vector<Point2D> .

    
risposta data 06.03.2013 - 08:13
fonte
3

Per dare una risposta più generale, le variabili dovrebbero essere raggruppate in un oggetto quando è logico farlo.

  • Le variabili sono aspetti o proprietà diverse di una "cosa"?
  • Appartengono sempre insieme?
  • Verranno utilizzati abbastanza per giustificare eventuali lavori extra che potrebbero essere coinvolti nella creazione di un oggetto?

Nel tuo caso, direi che il tuo codice migliora chiaramente quando raggruppa le variabili insieme.

Ma se le variabili vengono schiaffeggiate insieme in un oggetto che non è ben concepito, puoi rimanere bloccato con un design pesante che è peggio rispetto all'utilizzo di variabili normali.

Al contrario, è possibile sovra-progettare: spendere troppo tempo a pensare e costruire la struttura "perfetta" orientata agli oggetti, al punto che ti impedisce di fare effettivamente le cose.

    
risposta data 06.03.2013 - 09:34
fonte
1

In realtà, penso che il modo migliore sia farlo:

Vector<int> offset(10, 40);
element.moveBy(offset);

Questo codice astrae la dimensionalità dei tuoi vettori e la stessa riga di codice ( element.moveBy(offset) ) funzionerà invariata se cambi i tuoi vettori in 3D, o raddoppia, o anche coordinate polari, purché i tuoi tipi implementino il operazioni richieste correttamente.

Ad esempio, considera il seguente codice:

Vec wallBounce(Obj& o, cont Wall& w) {
    assert(isUnit(w.normal));
    Vec perp = dot(w.normal, o.velocity) * w.normal;
    o.velocity -= 2 * perp;
}

Chiunque abbia abbastanza indizi matematici vettoriali comprenderà cosa succede qui; Inoltre, la funzione è breve, al punto. Non puoi vedere a che cosa% typèf'd è fatto, ma di solito non è molto interessante e anche banale da cercare; la chiarezza e la brevità del codice sono più che compensanti. Dopo tutto, la codifica consiste nel fare astrazioni e astrarre gruppi di scalari in vettori è un'astrazione molto potente. Per i calci, prova a implementare la funzione precedente senza rendendo queste astrazioni, per vettori 2D, vettori 3D e scalari.

    
risposta data 06.03.2013 - 09:29
fonte

Leggi altre domande sui tag