Invio di tutto l'oggetto dati come argomento o solo campi richiesti?

7

Diciamo che ho una classe che memorizza solo i dati:

ClassData
    Field1
    Field2
    Field3

Ora diciamo che ho una funzione che utilizza Field1 e Field2:

public void DoStuff(string field1, string field2){
    if(field1 == "something"){ 
        //Do something
    }
    if(field2 == "somethingElse"){
        //Do something else
    }
}

vs

public void DoStuff(ClassData data){
    if(data.field1 == "something"){ 
        //Do something
    }
    if(data.field2 == "somethingElse"){
        //Do something else
    }
}

Sembra che questo sia un tipo di cosa di tipo "più arte che scienza", ma ho anche alcuni pensieri. Il passaggio di campi specifici mostra le informazioni richieste fin dall'inizio, che possono facilitare la lettura e la comprensione della funzione. L'invio di solo l'oggetto dati presenta vantaggi perché rende il codice più pulito. Non sarei sorpreso se mi mancassero pro e contro per entrambi e sarei interessato ad ascoltare ciò che pensi. Grazie!

    
posta sooprise 06.07.2011 - 16:25
fonte

5 risposte

6

Non posso dire senza ulteriori informazioni.

Come scritto sopra, il metodo DoStuff opera solo sui campi dell'oggetto ClassData, quindi il metodo DoStuff dovrebbe appartenere direttamente alla classe ClassData.

    
risposta data 06.07.2011 - 16:43
fonte
5

Il termine "oggetto dati" non ha alcun significato . Descrive la struttura di un oggetto, non il suo scopo, il secondo dei quali è il modo normale (e generalmente corretto) di classificare un oggetto in OOP.

C'è un nome per un oggetto che incapsula gli argomenti per una particolare operazione. Si chiama un comando (o, meno frequentemente, un oggetto comando ).

Usalo quando intendi implementare il schema di comando . In particolare, quando devi "impostare" un'operazione e salvarla o passarla su un altro oggetto invece di eseguirla immediatamente.

Se non stai implementando il pattern di comando, allora una classe faux- "command" che non ha altro scopo che contenere argomenti è un codice odore . Indica che il tuo metodo ha troppi argomenti, il che indica inoltre che ha troppe responsabilità, il che va contro le indicazioni fornite da Principio di Responsabilità Unica .

Gli oggetti non sono pensati per incapsulare dati , hanno lo scopo di incapsulare comportamento . Esistono alcune eccezioni notevoli alla regola, come comandi, eventi e DTO, ma al di fuori di casi molto specifici, dovresti essere sospettoso di qualsiasi classe senza comportamento. Creane uno solo se hai una chiara ragione per farlo. Se ti accorgi di fare questo molto semplicemente per risparmiare le battiture, probabilmente devi rivalutare il tuo design.

    
risposta data 06.07.2011 - 16:42
fonte
1

I campi 1 e 2 corrispondono logicamente o rappresentano qualcosa di significativo se presi come un insieme di dati?

In tal caso, forse DoStuff dovrebbe accettare un tipo di oggetto diverso da ClassData che forse ClassData può fornire o implementare come interfaccia.

Ad esempio, se campo1 e campo2 sono in realtà il nome e il numero della carta e ClassData è un oggetto che rappresenta un ordine, forse DoStuff potrebbe accettare una carta di credito. E forse ClassData potrebbe implementare un'interfaccia Card che fornisce l'accesso a quei campi.

Altro qui: link

In alternativa, forse DoStuff dovrebbe essere un metodo su un oggetto che contiene campo1 e campo2, che è quindi un campo in ClassData.

    
risposta data 06.07.2011 - 16:44
fonte
0

È probabile che tu abbia ricevuto i dati nei campi o come oggetto?

Se lasci passare solo il singolo oggetto, preparati a creare una nuova istanza se tutto quello che hai sono i campi. Lo stesso è vero nel retro. Questa è la sentenza che devi pronunciare.

    
risposta data 06.07.2011 - 16:30
fonte
0

Steve McConnell risponde a questo nel suo libro definito Codice completo . La risposta (credo sia nel capitolo sei) è che dovresti sempre passare nei campi necessari, e non l'oggetto che li contiene.

Il suo esempio è il calcolo delle indennità di congedo per un dipendente. Supponiamo che tu possa sempre calcolare l'assegno di ferie in base alla loro classe lavorativa, anzianità e anni di servizio. Puoi farlo:

calculateLeave (Employee e)

o

calculateLeave (JobClass j, Seniority s, int yearsOfService);

Il primo sembra più semplice. Ma cosa succede se si desidera calcolare l'assegno di uscita di un impiegato teorico? Nel primo caso dovresti costruire un oggetto Dipendente per una persona inesistente solo per fare il calcolo. E non avresti modo di sapere esattamente quali campi il metodo stava guardando.

    
risposta data 06.07.2011 - 19:58
fonte

Leggi altre domande sui tag