Passare campi (variabili d'istanza) per argomenti (parametri) all'interno di un oggetto - ha senso? [duplicare]

2

Credo che questa sia una domanda agnostica sulla lingua: se non lo è, correggimi.

Diciamo che ho una classe (lo snippet di codice è una sorta di "pseudo codice")

class Car:
  private steering_wheel
  private engine
  public Car(steering_wheel, engine):
    this.steering_wheel = steering_wheel
    this.engine = engine


  public void service():
     clean_steering_wheel()
     repair_engine()

  private void clean_steering_wheel():
    this.steering_wheel.do_stuff()

  private void repair_engine():
    this.engine.do_stuff()

che funziona bene! Ma potrei anche cambiare un po 'i metodi privati e lasciare che usino i campi (i.e steering_wheel e engine ) via argomenti, non direttamente

   class Car:
  private steering_wheel
  private engine
  public Car(steering_wheel, engine):
    this.steering_wheel = steering_wheel
    this.engine = engine


  public void service():
     clean_steering_wheel(this.steering_wheel)
     repair_engine(this.engine)

  private void clean_steering_wheel(steering_wheel):
    steering_wheel.do_stuff()

  private void repair_engine(engine):
    engine.do_stuff()

Supponiamo che tutti i parametri (argomenti) siano passati per riferimento.

Quali sono i vantaggi e gli svantaggi di queste soluzioni? Quale è considerato una pratica migliore? Quale preferisci?

    
posta Filip Bartuzi 16.11.2015 - 23:29
fonte

2 risposte

2

Sembra molto un giudizio sulla tua situazione specifica, ma mi vengono in mente alcune considerazioni. Se i metodi sono privati e non hai alcun motivo per per passare il parametro, probabilmente lo eviterei se per nessun altro motivo fosse meno complesso. Si potrebbe anche obiettare che esiste un motivo di rendimento per evitarlo, poiché non vi è alcun motivo per passare ulteriori parametri nello stack se non sono necessari.

Una volta trovo che I do passa un membro come parametro è con membri protetti. Diciamo che una classe di bambini fa qualcosa come aggiungere un secondo volante che deve anche essere pulito. In tal caso, potrebbe (presumibilmente) riutilizzare il metodo clean_steering_wheel dalla classe base e passare un altro membro del volante.

    
risposta data 16.11.2015 - 23:57
fonte
1

Il passaggio del campo come parametro esplicito è migliore se non stai invocando un metodo, ma una funzione / metodo statico: Meno dati sono disponibili in una funzione, più esplicite sono tutte le dipendenze, più è facile ragionare su quel codice. Quindi una funzione clean_steering_wheel(steering_wheel) non sorprenderà un utente effettivamente facendo qualcosa con il motore.

Tuttavia, un metodo (privato) riceverà già riferimenti al engine e steering_wheel tramite il parametro implicito this . Se hai un parametro this oltre a un parametro steering_wheel esplicito, stai duplicando i tuoi dati, il che può portare a incongruenze. In particolare, mi chiedo perché non hai utilizzato steering_wheel da this : Stai operando su steering_wheel di un diverso Car ? Su steering_wheel che non appartiene a nessun Car ?

Alla luce di ciò, sarebbe meno confuso definire clean_steering_wheel come

private void clean_steering_wheel():
  this.steering_wheel.do_stuff()

Tuttavia, sarebbe ancora meglio usare una funzione gratuita:

void function clean_steering_wheel(steering_wheel):
  steering_wheel.do_stuff()

void function repair_engine(engine):
  engine.do_stuff()

class Car:
  ...

  public void service():
    clean_steering_wheel(this.steering_wheel)
    repair_engine(this.engine)

, o metodo statico:

class Car:
  ...

  public void service():
    clean_steering_wheel(this.steering_wheel)
    repair_engine(this.engine)

  private static void clean_steering_wheel(steering_wheel):
    steering_wheel.do_stuff()

  private static void repair_engine(engine):
    engine.do_stuff()

Quale approccio preciso da utilizzare è abbastanza specifico per la lingua e ha anche un impatto sulla testabilità. Per esempio. in C ++, l'uso di funzioni libere in uno spazio dei nomi anonimo offre il miglior incapsulamento, ma ostacola attivamente la testabilità. Le funzioni dei membri statici privati potrebbero essere migliori, poiché possono essere testate da una classe di amici. In Java, non puoi avere funzioni libere, ma devi usare "metodi statici", quindi la discussione non è necessaria.

    
risposta data 18.11.2015 - 11:49
fonte