Quando utilizzare il concatenamento
Il concatenamento delle funzioni è per lo più popolare con le lingue in cui un IDE con completamento automatico è un luogo comune. Ad esempio, quasi tutti gli sviluppatori C # utilizzano Visual Studio. Pertanto, se stai sviluppando con C # aggiungendo il concatenamento ai tuoi metodi puoi essere un risparmiatore di tempo per gli utenti di quella classe perché Visual Studio ti aiuterà a costruire la catena.
D'altra parte, linguaggi come PHP di natura altamente dinamica e che spesso non supportano il completamento automatico negli IDE vedranno meno classi che supportano il concatenamento. Il concatenamento sarà appropriato solo quando vengono utilizzati phpDocs corretti per esporre i metodi concatenabili.
Che cos'è il concatenamento?
Dato una classe chiamata Foo
i seguenti due metodi sono entrambi concatenabili.
function what() { return this; }
function when() { return new Foo(this); }
Il fatto che uno sia un riferimento all'istanza corrente e uno crea una nuova istanza non cambia che questi sono 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 attraversare due diverse classi. Ad 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 precedenti. 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 è incatenato quando il suo valore di ritorno viene usato 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 utilizzare this
e new(this)
Le stringhe nella maggior parte delle lingue sono immutabili. Pertanto, le chiamate al metodo di concatenamento portano sempre alla creazione di nuove stringhe. Dove può essere modificato un oggetto come StringBuilder.
La coerenza è la migliore pratica.
Se disponi di metodi che modificano lo stato di un oggetto e restituiscono this
, non utilizzare 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 cosa sta succedendo all'interno di a
.
Il passo fuori e dietro trucco
Io chiamo questo trucco di uscire e tornare , perché risolve molti problemi comuni legati al concatenamento. Significa fondamentalmente che esci dalla classe originale in una nuova classe temporanea e poi torni alla classe originale.
La classe temporanea esiste solo per fornire funzionalità speciali alla classe originale, ma solo in condizioni speciali.
Spesso ci sono momenti in cui una catena deve cambiare lo 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 di tornare a A
.
Ecco il mio esempio, lascia che lo stato speciale sia conosciuto come 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
potrebbe tornare a un nuovo super-tipo di A
con metodi diversi.