È un principio di base, o altamente desiderabile, avere metodi di classe che restituiscano "$ this" piuttosto che un valore?

8

Ho appena iniziato a imparare OOP. Ho iniziato circa un anno fa e ho scritto probabilmente 15000 righe di esso. Ma ho scritto tutto con pochissima esperienza guardando l'OOP di altre persone.

La maggior parte delle mie funzioni di classe restituiscono un valore o apportano una modifica alle proprietà della classe e restituiscono true / false. Alcuni di quelli che restituiscono un valore salvano anche quel valore in una proprietà di classe (dopo aver controllato prima se la proprietà della classe è già impostata, il che può evitare una chiamata al database).

Ora sto facendo molti scavi su Magento / Zend e noto che molti dei loro metodi di classe restituiscono "$ this". A quanto ho capito, a differenza delle normali funzioni, i metodi di classe restituiscono $ questo atto per riferimento non in base al valore, in modo da ottenere lo stesso oggetto iniziato anziché una copia.

Restituisce $this qualcosa che dovrei fare molto di più? Rende il codice più facile da mantenere e utilizzare? È necessario restituire $this necessario per concatenare i metodi di classe?

    
posta Buttle Butkus 30.01.2013 - 01:59
fonte

3 risposte

14

Questa è una tecnica impiegata per creare interfacce fluenti. Se una Fluent Interface non è il tuo obiettivo, non è necessario restituire $ this.

Le interfacce fluide ti consentono di scrivere codice simile a questo (pseudocodice):

private void makeFluent(Customer customer) {
    customer.newOrder()
            .with(6, "TAL")
            .with(5, "HPK").skippable()
            .with(3, "LGV")
            .priorityRush();
}

Funziona, perché ogni chiamata al metodo ha accesso all'oggetto originale, in virtù della chiamata al metodo precedente che restituisce this . Il codice precedente è più o meno equivalente a:

private void makeFluent(Customer customer) {
    var newOrder = customer.newOrder()
    newOrder.with(6, "TAL");
    newOrder.with(5, "HPK", skippable := true);
    newOrder.with(3, "LGV");
    newOrder.priorityRush();
    ...
}

this non viene sempre restituito. A volte viene restituito un oggetto diverso. Linq funziona in questo modo, restituendo un IEnumerable (una rappresentazione pigra di una raccolta, un motore di stato modificato, in pratica) da ciascun metodo Linq nella catena.

Richiede più sforzo e lungimiranza per creare un'interfaccia fluida rispetto a quella di impostare semplicemente tutti i parametri in un costruttore. Devi capire se l'oggetto ha tutto ciò di cui ha bisogno per essere completamente funzionale, e non è sempre chiaro esattamente cosa fa un determinato metodo, o in quale ordine è necessario chiamare i metodi. Ad esempio:

20.minutes.ago

sembra pulito, ma come funziona esattamente?

link
link

    
risposta data 30.01.2013 - 16:45
fonte
2

Restituendo $ restituisce un'istanza dell'oggetto di cui il metodo è membro. Ci sono molti casi in cui vorresti farlo, ma finché non capisci esattamente cosa ho appena detto significa e puoi identificare un caso d'uso per questo, non ne hai davvero bisogno.

Esempi di quando usare questo:

Un btree è un esempio in PHP di dove restituiresti un figlio di $ this, che non è esattamente la stessa cosa ma penso che abbia a che fare con questa discussione.

Scrivendo il tuo costruttore ti restituirei sempre $ this

Per chiarire i riferimenti, quando restituisci $ questo stai trasmettendo un riferimento all'oggetto di cui fa parte il metodo in esecuzione. Penso che le regole di PHP per quando funziona su un riferimento rispetto a un valore a volte non sono chiare, ma in questo caso $ è sempre un riferimento. Per essere chiari: un riferimento è sempre "l'istanza che hai" e mai una copia, mentre un "valore" è una copia. Questi sono due tipi di semantica argomento

    
risposta data 30.01.2013 - 02:09
fonte
1

"Un riferimento PHP è un alias, che consente a due variabili diverse di scrivere sullo stesso valore. A partire da PHP 5, una variabile oggetto non contiene più l'oggetto stesso come valore. Contiene solo un identificatore di oggetto che consente gli oggetti object per trovare l'oggetto reale. Quando un oggetto viene inviato per argomento, restituito o assegnato a un'altra variabile, le diverse variabili non sono alias: contengono una copia dell'identificatore, che punta allo stesso oggetto. "

Il vero vantaggio di restituire $ è nei modelli di progettazione della composizione degli oggetti, specialmente in Magento. Prendiamo ad esempio Mage_Core_Sales_Order_Invoice- > capture () che restituisce $ this. Questo metodo assomiglia a:

  public function capture()
    {
        $this->getOrder()->getPayment()->capture($this);
        if ($this->getIsPaid()) {
            $this->pay();
        }
        return $this;
    }

la linea:

$this->getOrder()->getPayment()->capture($this);

Passa il modello di fattura come riferimento, molto utile nei modelli di composizione degli oggetti. Il ritorno di $ è anche un riferimento. Pertanto, il metodo che chiama - > capture () su un modello di fattura può continuare a lavorare con una chiamata a oggetti concatenata per la leggibilità del codice contestuale.

    
risposta data 21.02.2013 - 08:31
fonte

Leggi altre domande sui tag