Каскадирование методов
В объектно-ориентированном программировании каскадирование методов — это синтаксис несколько методов , который позволяет вызывать для одного и того же объекта. Это особенно применимо в плавных интерфейсах .
Например, в Dart каскад:
a..b()
..c();
эквивалентно отдельным вызовам:
a.b();
a.c();
Каскадирование методов встречается гораздо реже, чем цепочка методов — оно встречается только в нескольких объектно-ориентированных языках, тогда как цепочка очень распространена. Форма каскадирования может быть реализована с использованием цепочки, но это ограничивает интерфейс; см. сравнение с цепочкой методов ниже.
Приложение
[ редактировать ]Каскадирование — это синтаксический сахар , который устраняет необходимость многократного перечисления объекта. Это особенно используется в интерфейсах Fluent , которые содержат множество вызовов методов для одного объекта.
Это особенно полезно, если объект является значением длинного выражения, поскольку устраняет необходимость повторного перечисления выражения или использования временной переменной. Например, вместо повторного перечисления выражения:
a.b().c();
a.b().d();
или используя временную переменную:
n = a.b();
n.c();
n.d();
каскадирование позволяет написать выражение один раз и использовать его повторно:
a.b()..c()
..d();
Сравнение с цепочкой методов
[ редактировать ]Учитывая вызов метода a.b()
, после выполнения вызова каскадный метод оценивает это выражение для левого объекта a
(с его новым значением, если оно изменено), в то время как цепочка методов оценивает это выражение как правильный объект.
- Цепочка
Следующая цепочка (на C++):
a.b().c();
эквивалентно простой форме:
b = a.b();
b.c();
- Каскадный
Следующий каскад (в Dart):
a..b()
..c();
эквивалентно простой форме:
a.b();
a.c();
Каскадирование может быть реализовано в виде цепочки, если методы возвращают целевой объект (приемник, this
, self
). Однако для этого необходимо, чтобы метод был уже реализован таким образом – или исходный объект был обернут в другой объект, который делает это – и чтобы метод не возвращал какое-либо другое, потенциально полезное значение (или ничего, если это будет более уместно, как в сеттеры). В Fluent-интерфейсах это часто означает, что сеттеры возвращают это вместо ничего.
Языки
[ редактировать ]Паскаль
[ редактировать ]В операторе компонента оператора with компоненты (поля) переменной записи, указанные в предложении with , могут быть обозначены только идентификатором их поля, т.е. без предшествующего им обозначения всей переменной записи. Предложение with фактически открывает область, содержащую идентификаторы полей указанной переменной записи, так что идентификаторы полей могут встречаться как идентификаторы переменных.
with date do
if month = 12 then
begin month := 1; year := year + 1 end
else month := month + 1
{ is equivalent to }
if date.month = 12 then
begin date.month := 1; date.year := date.year + 1 end
else date.month := date.month + 1
Смолток
[ редактировать ]Цепочки методов и каскады были введены в Smalltalk ; большинство последующих объектно-ориентированных языков реализовали цепочки, но лишь немногие реализовали каскады. В Smalltalk оператор точка с запятой может использоваться для отправки разных сообщений одному и тому же объекту: [1]
self listPane parent
color: Color black;
height: 17;
width: 11
Сравните с отдельными операторами, оканчивающимися точкой, также использующими переменную для сокращения:
|parent|
parent := self listPane parent.
parent color: Color black.
parent height: 17.
parent width: 11.
Одна тонкость заключается в том, что значение вызова метода («сообщения») в каскаде по-прежнему является обычным значением сообщения, а не получателя. Это проблема, когда вам действительно нужно значение получателя, например, при создании сложного значения. Эту проблему можно обойти с помощью специального yourself
метод, который просто возвращает получателя: [2]
Object>>yourself
^self
Например, метод «добавить объект в коллекцию» ( Collection>>add: anObject
) возвращает добавленный объект, а не коллекцию. Таким образом, чтобы использовать это в каскаде в операторе присваивания, каскад должен заканчиваться yourself
, в противном случае значением будет просто последний добавленный элемент, а не сама коллекция:
all := OrderedCollection new
add: 5;
add: 7;
yourself.
Визуальный Бейсик
[ редактировать ]Visual Basic использует With
оператор , позволяющий произвольное количество вызовов методов или доступов к свойствам одного и того же объекта:
With ExpressionThatReturnsAnObject
.SomeFunction(42)
.Property = value
End With
With..End With
блоки в Visual Basic могут быть вложенными:
With ExpressionThatReturnsAnObject
.SomeFunction(42)
.Property = value
With .SubObject
.SubProperty = otherValue
.AnotherMethod(42)
End With
End With
Дарт
[ редактировать ]Среди новых языков Dart реализует каскады, используя двойную точку. ..
«операция каскадного вызова метода». В отличие от Smalltalk, в Dart значением вызова каскадного метода является получатель (базовый объект), а не значение (некаскадного) вызова метода, поэтому нет необходимости yourself
. Dart использует свойства , поэтому вместо использования синтаксиса методов для геттеров и сеттеров ( foo.getBar(); foo.setBar(b);
), он использует синтаксис значения поля/присвоения ( foo.bar; foo.bar = b;
), а каскады работают с заданиями:
a..string = 'Hello world!'
..done = true;
эквивалентно:
a.string = 'Hello world!';
a.done = true;
Ссылки
[ редактировать ]- Бек, Кент (1997). Шаблоны лучших практик Smalltalk . Прентис Холл. ISBN 978-0134769042 .
Внешние ссылки
[ редактировать ]- Дарт
- « Каскады методов в дартс », Гилад Браха, 17 февраля 2012 г.
- Этап 1. Изменения языка , « Каскады », Боб Нистром, июль 2012 г. (обновлено в марте 2013 г.)