Kiedy stosować łańcuchy?
Tworzenie łańcuchów funkcji jest najbardziej popularne w językach, w których powszechne jest IDE z autouzupełnianiem. Na przykład prawie wszyscy programiści C # używają programu Visual Studio. Dlatego jeśli programujesz w języku C #, dodawanie łańcuchów do swoich metod może być oszczędnością czasu dla użytkowników tej klasy, ponieważ Visual Studio pomoże ci w budowaniu łańcucha.
Z drugiej strony, języki takie jak PHP, które są z natury bardzo dynamiczne i często nie mają obsługi autouzupełniania w IDE, zobaczą mniej klas obsługujących tworzenie łańcuchów. Tworzenie łańcuchów będzie odpowiednie tylko wtedy, gdy do ujawnienia metod łańcuchowych zostaną użyte poprawne phpDocs.
Co to jest łączenie?
Biorąc pod uwagę klasę o nazwie, Foo
dwie następujące metody są łańcuchowe.
function what() { return this; }
function when() { return new Foo(this); }
Fakt, że jest to odniesienie do bieżącej instancji i tworzy się nową instancję, nie zmienia faktu, że są to metody łańcuchowe.
Nie ma złotej zasady, że metoda łańcuchowa musi odwoływać się tylko do bieżącego obiektu. Rzeczywiście, metody łańcuchowe mogą być w dwóch różnych klasach. Na przykład;
class B { function When() { return true; } };
class A { function What() { return new B(); } };
var a = new A();
var x = a.What().When();
W this
żadnym z powyższych przykładów nie ma odniesienia . Kod a.What().When()
jest przykładem łączenia. Co ciekawe, typ klasy B
nigdy nie jest przypisywany do zmiennej.
Metoda jest łączona łańcuchowo, gdy jej wartość zwracana zostanie wykorzystana jako następny składnik wyrażenia.
Oto kilka innych przykładów
// 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();
Kiedy stosować this
inew(this)
Ciągi znaków w większości języków są niezmienne. Tak więc wywołania metod łączenia zawsze skutkują tworzeniem nowych ciągów. Gdzie jako obiekt taki jak StringBuilder może być modyfikowany.
Spójność jest najlepszą praktyką.
Jeśli masz metody modyfikujące stan obiektu i zwracające this
, nie mieszaj metod zwracających nowe instancje. Zamiast tego utwórz specjalną metodę o nazwie Clone()
, która zrobi to jawnie.
var x = a.Foo().Boo().Clone().Foo();
To jest o wiele jaśniejsze, co dzieje się w środku a
.
Krok na zewnątrz i do tyłu
Nazywam to lewą i lewą sztuczką, ponieważ rozwiązuje wiele typowych problemów związanych z łańcuchem. Zasadniczo oznacza to, że wychodzisz z oryginalnej klasy do nowej klasy tymczasowej, a następnie wracasz do oryginalnej klasy.
Klasa tymczasowa istnieje tylko w celu zapewnienia specjalnych cech oryginalnej klasie, ale tylko w szczególnych warunkach.
Często zdarza się, że łańcuch musi zmienić stan , ale klasa A
nie może reprezentować wszystkich tych możliwych stanów . Tak więc podczas łańcucha wprowadzana jest nowa klasa, która zawiera odniesienie do A
. To pozwala programiście wejść w stan i wrócić do A
.
Oto mój przykład, niech stan specjalny będzie znany jako 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();
To jest bardzo prosty przykład. Jeśli chcesz mieć większą kontrolę, możesz B
wrócić do nowego supertypu, A
który ma różne metody.