Когда использовать цепочку
Цепочка функций в основном популярна в языках, где IDE с автозаполнением является обычным явлением. Например, почти все разработчики C # используют Visual Studio. Поэтому, если вы разрабатываете на C #, добавление цепочек к вашим методам может сэкономить время для пользователей этого класса, поскольку Visual Studio поможет вам в создании цепочки.
С другой стороны, такие языки, как PHP, которые по своей природе очень динамичны и часто не имеют поддержки автозаполнения в IDE, увидят меньше классов, поддерживающих сцепление. Цепочка будет уместна только тогда, когда правильные phpDocs используются для раскрытия цепочечных методов.
Что такое цепочка?
Для Foo
заданного класса следующие два метода являются цепочечными.
function what() { return this; }
function when() { return new Foo(this); }
Тот факт, что каждый является ссылкой на текущий экземпляр, а другой создает новый экземпляр, не меняет того, что это цепные методы.
Не существует золотого правила о том, что цепочечный метод должен ссылаться только на текущий объект. Infact, цепные методы могут быть в двух разных классах. Например;
class B { function When() { return true; } };
class A { function What() { return new B(); } };
var a = new A();
var x = a.What().When();
Нет ссылок ни this
в одном из приведенных выше примеров. Код a.What().When()
является примером цепочки. Интересно то, что тип класса B
никогда не присваивается переменной.
Метод сцепляется, когда его возвращаемое значение становится следующим компонентом выражения.
Вот еще один пример
// 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();
Когда использовать this
иnew(this)
Строки в большинстве языков неизменны. Поэтому вызовы метода цепочки всегда приводят к созданию новых строк. Где как объект типа StringBuilder может быть изменен.
Последовательность - лучшая практика.
Если у вас есть методы, которые изменяют состояние объекта и возвращают его this
, не смешивайте методы, которые возвращают новые экземпляры. Вместо этого создайте определенный метод с именем, Clone()
который будет делать это явно.
var x = a.Foo().Boo().Clone().Foo();
Это намного яснее относительно того, что происходит внутри a
.
Шаг снаружи и назад трюк
Я называю это уловкой шага назад и назад , потому что это решает много общих проблем, связанных с цепочкой. По сути, это означает, что вы выходите из исходного класса в новый временный класс, а затем возвращаетесь к исходному классу.
Временный класс существует только для предоставления специальных функций исходному классу, но только в особых условиях.
Часто цепочке необходимо изменить состояние , но класс A
не может представлять все эти возможные состояния . Таким образом, во время цепочки вводится новый класс, который содержит ссылку на A
. Это позволяет программисту перейти в состояние и вернуться в A
.
Вот мой пример, пусть специальное состояние будет известно как 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();
Это очень простой пример. Если вы хотите иметь больше контроля, то B
можете вернуться к новому супертипу A
с другими методами.