Коли використовувати ланцюжок
Функціонування ланцюга в основному популярне серед мов, де IDE з автоматичним завершенням є загальним місцем. Наприклад, майже всі розробники C # використовують Visual Studio. Тому, якщо ви розробляєте додавання ланцюга на C # до своїх методів, це може заощадити час для користувачів цього класу, оскільки Visual Studio допоможе вам у створенні ланцюга.
З іншого боку, такі мови, як PHP, які мають дуже динамічний характер і часто не мають автоматичної повної підтримки в IDE, побачать менше класів, які підтримують ланцюжок. Ланцюг буде доречним лише тоді, коли для розкриття можливих методів будуть використані правильні phpDocs.
Що таке ланцюжок?
З огляду на клас, названий, Fooдва наступні способи є можливими.
function what() { return this; }
function when() { return new Foo(this); }
Той факт, що один є посиланням на поточний екземпляр, а інший створює новий екземпляр, не змінюється, що це є можливими методами.
Не існує жодного золотого правила, згідно з яким метод, який можна отримати, повинен посилатися лише на поточний об'єкт. Взаємодія, доступні методи можуть бути в двох різних класах. Наприклад;
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який має різні методи.