Quando usare il concatenamento
Il concatenamento di funzioni è molto popolare tra le lingue in cui un IDE con il completamento automatico è un luogo comune. Ad esempio, quasi tutti gli sviluppatori C # utilizzano Visual Studio. Pertanto, se stai sviluppando con C # l'aggiunta di concatenamento ai tuoi metodi può essere un risparmio di tempo per gli utenti di quella classe perché Visual Studio ti aiuterà a costruire la catena.
D'altra parte, linguaggi come PHP che sono altamente dinamici in natura e spesso non hanno il supporto di auto-completamento negli IDE vedranno meno classi che supportano il concatenamento. Il concatenamento sarà appropriato solo quando si impiegano phpDocs corretti per esporre i metodi concatenabili.
Che cos'è il concatenamento?
Data una classe denominata, Foo
i due metodi seguenti sono entrambi concatenabili.
function what() { return this; }
function when() { return new Foo(this); }
Il fatto che uno sia un riferimento all'istanza corrente e che crei una nuova istanza non cambia il fatto che si tratti di metodi concatenabili.
Non esiste una regola d'oro secondo cui un metodo concatenabile deve fare riferimento solo all'oggetto corrente. Infatti, i metodi concatenabili possono essere suddivisi in due classi diverse. Per esempio;
class B { function When() { return true; } };
class A { function What() { return new B(); } };
var a = new A();
var x = a.What().When();
Non c'è alcun riferimento a this
in nessuno degli esempi sopra. Il codice a.What().When()
è un esempio di concatenamento. La cosa interessante è che il tipo di classe B
non è mai assegnato a una variabile.
Un metodo viene concatenato quando il valore restituito viene utilizzato come componente successivo di un'espressione.
Ecco qualche altro esempio
// return value never assigned.
myFile.Open("something.txt").Write("stuff").Close();
// two chains used in expression
int x = a.X().Y() * b.X().Y();
// a chain that creates new strings
string name = str.Substring(1,10).Trim().ToUpperCase();
Quando usare this
enew(this)
Le stringhe nella maggior parte delle lingue sono immutabili. Quindi il concatenamento delle chiamate dei metodi comporta sempre la creazione di nuove stringhe. Dove come oggetto come StringBuilder può essere modificato.
La coerenza è la migliore pratica.
Se disponi di metodi che modificano lo stato di un oggetto e restituiscono this
, non mescolare metodi che restituiscono nuove istanze. Invece, crea un metodo specifico chiamato Clone()
che lo farà esplicitamente.
var x = a.Foo().Boo().Clone().Foo();
Questo è molto più chiaro su ciò che sta accadendo all'interno a
.
Il passo fuori e trucco indietro
Io chiamo questo il trucco di andata e ritorno , perché risolve molti problemi comuni legati al concatenamento. Fondamentalmente significa che esci dalla classe originale in una nuova classe temporanea e poi torna alla classe originale.
La classe temporanea esiste solo per fornire funzionalità speciali alla classe originale, ma solo a condizioni speciali.
Ci sono volte in cui una catena deve cambiare stato , ma la classe A
non può rappresentare tutti quei possibili stati . Quindi durante una catena viene introdotta una nuova classe che contiene un riferimento a A
. Ciò consente al programmatore di entrare in uno stato e tornare a A
.
Ecco il mio esempio, sia noto lo stato speciale B
.
class A {
function Foo() { return this; }
function Boo() { return this; }
function Change() return new B(this); }
}
class B {
var _a;
function (A) { _a = A; }
function What() { return this; }
function When() { return this; }
function End() { return _a; }
}
var a = new A();
a.Foo().Change().What().When().End().Boo();
Questo è un esempio molto semplice. Se si desidera avere un maggiore controllo, è B
possibile tornare a un nuovo super-tipo A
con metodi diversi.