Коли використовувати ланцюжок
Функціонування ланцюга в основному популярне серед мов, де 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
який має різні методи.