Quali sono i vantaggi / svantaggi dell'uso di oggetti come parametri per altri metodi di oggetti?

5

Sto pensando principalmente a PHP qui, ma se vuoi fare riferimento ad altre lingue va bene.

Un oggetto ha un metodo che richiede dati contenuti in un'altra classe di oggetti.

Dovrei estrarre i dati dall'altro oggetto in una variabile e quindi inviare solo quei dati all'oggetto richiedente?

O dovrei passare l'intero oggetto contenente i dati nell'oggetto che richiede i dati e poi fare in modo che l'oggetto richiedente esegua le operazioni di estrazione dei dati?

Te lo chiedo perché sto lavorando a un grande progetto per cui ho scritto il 100% del codice, e alcuni dei miei primi codici contengono argomenti stringa o numerici, ma il mio codice successivo sembra essere incline a passare intorno agli oggetti. Mentre mi imbatto in un vecchio codice, mi chiedo se dovrei convertirlo ai parametri dell'oggetto.

    
posta Buttle Butkus 23.08.2013 - 01:41
fonte

5 risposte

4

Penso che come ogni domanda CS, dipende.

  1. Se hai intenzione di utilizzare molte delle funzionalità fornite dalla classe passata, è fantastico:
    • questo è fondamentalmente il modo in cui puoi avere funzioni comuni come sort, che possono prendere qualsiasi tipo di oggetto e finché avrà i metodi richiesti implementati funzionerà.
    • passare oggetti facilita la programmazione su un'interfaccia
  2. Se stai solo estraendo una cosa (diciamo integer) e usando i metodi delle classi di ricezione per operare su di essa, è male:
    • potresti copiare involontariamente l'oggetto mentre passi
    • se non usi l'intero oggetto il codice può essere fuorviante

Quindi ti consiglio di guardare le tue funzioni caso per caso e non fare generalizzazioni per l'intero codice base.

    
risposta data 23.08.2013 - 04:29
fonte
2

Dipende e cerco di discuterne usando un esempio più realistico.

Ad esempio, supponiamo di avere un oggetto Person con attributi come FirstName , Surname , NameAffix , DateOfBirth , Gender . E stai per creare alcuni metodi per elaborare quei dati (ad esempio, per un rapporto formattato).

Per prima cosa, pensiamo a un metodo GetFullPersonNameFormatted , che dovrebbe restituire una combinazione di FirstName , Surname e NameAffix in una stringa specificatamente formattata (supponiamo che non abbia senso mettere il metodo direttamente in la classe Person per alcuni motivi). Passerai gli attributi uno alla volta o l'intero oggetto Person ? Beh, probabilmente passerei l'oggetto Person a un intero, poiché questo metodo crea un'astrazione sulle persone, e se la persona cambia internamente, voglio solo cambiare GetFullPersonNameFormatted internamente, non il codice chiamante.

Ora pensiamo a un metodo GetDateOfBirthFormatted , dovrebbe restituire la data di nascita in un modo specificamente formattato. Passerai l'attributo o l'intero oggetto Persona? Probabilmente inizierei con un metodo più generale FormatDate(date) , non specifico per Persone, che sarebbe molto più riutilizzabile di un metodo GetDateOfBirthFormatted(person) , ma potrebbe anche avere senso avere un ulteriore

 string GetDateOfBirthFormatted(Person person)
 {
        return FormatDate(person.DateOfBirth);
 }

metodo per lo stesso motivo del primo esempio: creare un'astrazione sulle persone. Se hai davvero bisogno di quel metodo, dipende (per esempio, se ci sarebbe solo una chiamata a GetDateOfBirthFormatted nell'intero programma, potresti evitare di creare quel metodo e usare invece FormatDate(person.DateOfBirth) invece.

Quindi la risposta per "dovrebbe il tuo metodo prendere l'intero oggetto o no?" dipende principalmente da "quanto ha bisogno il tuo metodo da quell'oggetto?", ma anche da "che tipo di astrazione creerai?". Un grande indicatore per utilizzare meglio gli oggetti è quando ci sono molti metodi per ottenere lo stesso gruppo di attributi più e più volte, ad esempio, quando si passa FirstName , Surname , NameAffix in diversi metodi. Questo può anche essere un indicatore che questi attributi appartengono a una classe appena creata (pensate a un programma in cui non avete una classe Person finora: metodi come quello potrebbero essere un indicatore che dovresti crearne uno).

Ci può essere un'altra ragione non per passare oggetti, ma solo attributi: disaccoppiamento. Diciamo che GetFullPersonNameFormatted è nel modulo A, e la definizione di classe di Person è nel modulo B, e la chiamata a GetFullPersonNameFormatted è nel modulo C che fa riferimento a A e B. Se non vuoi fare riferimento a B da A, per mantenere questi due moduli completamente indipendenti l'uno dall'altro, è necessario definire GetFullPersonNameFormatted senza alcun parametro Person .

Riassumendo: non è sempre una semplice decisione in bianco e nero, e ci sono diverse sfumature di grigio.

    
risposta data 23.08.2013 - 08:53
fonte
1

Penso che la migliore regola empirica sia quella di inviare solo come parametro ciò che è effettivamente necessario. Il motivo è riutilizzare . Se hai solo bisogno di un numero intero come parametro, passare un oggetto significa che lo stesso metodo non può (senza alcun tipo di wrangling) funzionare in qualche altro contesto quando vuoi usare lo stesso metodo ma non hai un'istanza del tipo richiesto di oggetto da usare come parametro.

    
risposta data 23.08.2013 - 05:10
fonte
1

Confronto:

public function ReceiveData($s) {
    $data = ExtractData($s)
    ProcessData($data)
}
...
$destination.ReceiveData($source)

Con:

$destination.ProcessData(ExtractData($source))

Quest'ultimo ha diversi vantaggi concreti:

  1. Testabilità. È più semplice eseguire il test dell'unità ExtractData e ProcessData separatamente anziché un metodo (ReceiveData) che esegue entrambi.
  2. Riutilizzabilità. Se hai un diverso tipo di $ sorgente che $ destinazione potrebbe voler ricevere, puoi comunque utilizzare ProcessData semplicemente usando una funzione ExtractData diversa (o anche la stessa funzione ExtractData se i due tipi di $ fonte hanno un'interfaccia comune).
  3. Leggibilità. L'uso di ExtractData come argomento per ProcessData rende esplicita l'estrazione dei dati, piuttosto che una parte implicita di ReceiveData.

Questo si riferisce al principio single responsiblity (un metodo dovrebbe avere solo una responsabilità).

    
risposta data 23.08.2013 - 05:44
fonte
0
  • Penso che sia possibile impostare un oggetto come proprietà della classe e passare un oggetto come argomento del metodo. Scegli quale è determinato nella scena.

  • Se l'istanza utilizza i dati o la funzione di un oggetto, è necessario impostare l'oggetto come proprietà dell'istanza. Ad esempio, "Proxy Pattern", si chiama sempre il metodo di un oggetto per eseguire le attività.

  • Ma se la tua istanza utilizza i dati della funzione di qualsiasi oggetto, dovresti passare un oggetto come argomento di un metodo. Ad esempio, "Modello visitatore", la tua classe visita ogni volta un oggetto diverso. Quindi dovresti passare un oggetto come argomento.

risposta data 23.08.2013 - 04:35
fonte

Leggi altre domande sui tag