Migliore pratica OOP in C #: passaggio dell'oggetto come parametro VS creazione di una nuova istanza dell'oggetto

5

Prima di tutto, vorrei sapere se passare un oggetto come parametro è molto meglio che creare nuovamente un altro oggetto in una classe che lo utilizzerà di nuovo e in secondo luogo quali sono i pro e i contro di ciascuno di essi?

Ecco un esempio:

public class ClassWithTheObject
{

TheObject obj = new TheObject();

// Somewhere around the code
PassTheObjectHere anotherObj = new PassTheObjectHere(obj);

}

O semplicemente vai dritto dichiarando la classe TheObject nella classe PassTheObjectHere ? Il caso sarebbe che entrambe le classi ClassWithTheObject e PassTheObjectHere utilizzeranno la classe TheObject .

L'ultima domanda, il passaggio dell'oggetto è troppe volte causa alcuni effetti negativi sul programma?

Per favore mi illumini.

    
posta arvicxyz 04.12.2014 - 06:55
fonte

3 risposte

3

La tua domanda mostra alcuni equivoci, suppongo: se l'alternativa a

passing an object as parameter

è di creare una nuova istanza direttamente nel costruttore PassTheObjectHere , quindi ovviamente non stai usando alcun valore / stato del obj precedentemente creato in PassTheObjectHere . Se questo è il caso, è abbastanza inutile passare obj come parametro a PassTheObjectHere . In questo caso, in genere, verificherei che TheObject abbia qualsiasi variabile membro, il che potrebbe renderlo un candidato per una classe statica (ma non fraintendetemi, non sto dicendo l'uso di una classe statica migliorerebbe il design qui in qualsiasi modo).

D'altra parte, se il costruttore di PassTheObjectHere ha bisogno dei valori / stato del% creato in precedenza con% co_de per funzionare correttamente, sarebbe semplicemente sbagliato avere un costruttore come questo.

 PassTheObjectHere()
 {
      var obj = new TheObject();

      // ... do something which expects having obj
      // ... some values provided by the caller
 }

(spero che sia ovvio).

can passing the object too many times cause some bad effects on the program?

Questa non è una domanda di "troppe volte". Puoi passare oggetti circa 1000 volte correttamente, che va bene, e una volta sbagliato, che è male. Ad esempio, se si passa obj al costruttore e il costruttore modifica lo stato di obj in un modo che il chiamante non si aspetta (chiamato "effetto collaterale")

  PassTheObjectHere(TheObject obj)
  {
       // ... use methods/properties/values of obj 
       // ... for this constructor

       // and finally
       obj.MakeValuesInvalid();
  }

e il chiamante fa qualcosa di simile

public class ClassWithTheObject
{

   TheObject obj = new TheObject();
   obj.Initialize()
   PassTheObjectHere anotherObj = new PassTheObjectHere(obj);
   obj.MethodWhichExpectsObjToBeValid();
}

allora il tuo programma ora ha un bug. Esistono principalmente le seguenti alternative per proteggerti da questo:

  1. Evita l'effetto collaterale non cambiando "obj" all'interno del costruttore
  2. Se è necessario modificare "obj", eseguire una copia in anticipo all'interno del costruttore.
  3. non aggiungere alcun metodo a obj che permetta il cambiamento di qualsiasi stato interno di obj (che è chiamato "immutabilità")

Il numero 3 porta allo stesso codice di 1, ma con la protezione aggiuntiva contro l'introduzione di effetti collaterali non intenzionali in un secondo momento, quando TheObject potrebbe essere cambiato.

    
risposta data 04.12.2014 - 09:58
fonte
4

È un po 'più complicato di così.

In primo luogo, capire i compromessi. Se stai per passare una copia dell'oggetto (essenzialmente una semantica "passa per valore") piuttosto che un riferimento all'oggetto originale, stai per fare un grande successo. Se questo colpo è giustificato o meno dipende dai requisiti funzionali del tuo software.

In secondo luogo, potrebbe avere più senso semantica di scrivere metodi che accettano l'oggetto per riferimento, ma restituiscono un nuovo oggetto, invece di modificare l'oggetto passato sul posto o fare una copia di esso prima di passare al metodo.

var modified object = ReturnANewObjectFrom(theOriginalObject);

Quando crei e restituisci nuovi oggetti in questo modo, stai approfittando di immutabilità . Laddove l'immutabilità ha senso, è logico farlo. I programmi che utilizzano oggetti e strutture dati immutabili sono più facili da ragionare, specialmente quando si scrivono applicazioni concorrenti (applicazioni che fanno più di una cosa alla volta, di solito in thread separati o su core separati).

    
risposta data 04.12.2014 - 07:38
fonte
1

Penso che dipenda davvero dal contesto in cui stai lavorando. Nel tuo esempio, stai inviando l'istanza TheObject al costruttore di PassTheObjectHere, questo modo di lavorare mi dice che, all'interno della tua istanza PassTheObjectHere, stai lavorando con alcuni dati inizializzati precedenti. Quindi se ClassWithTheObject condividerà lo stato conversazionale dell'istanza TheObject, stai facendo bene. Questo è quello che penso

    
risposta data 04.12.2014 - 07:16
fonte