t.me/atinfo_chat Telegram группа по автоматизации тестирования

Последовательный вызов методов.

В программировании на Java очень часто встречаю “Последовательный вызов методов”.

Например:

driver.findElement(By.id("")).click();
или
loginPage.getData().verifyData();
или
method.getText().trim().verify();

И вроде бы разобрался, что каждый из методов возвращает класс следующего. Но каким образом ..click(); .verifyData(); и .verify(); определяют что произошло в предыдущем методе? Спасибо

P.S. Если есть возможность объясните на простом примере

никак :smile:

Определяет по наличию, наверное…Тут больше похоже на true/false: если нашло что-то - идёт дальше, нет - упало

А что значит “определяют что произошло в предыдущем”?
Это же последовательный вызов, а не последовательное определение.
На каждом шаге у нас есть объект и метод, который вызывается применительно к этому объекту.
Объект 1 - Метод 1
Объект 2 - Метод 2
Объект 3 - Метод 3
И это вроде как всё, что нам нужно.

Дело в том что например вот здесь есть пример:

print(getCity().getStreet().getHouse().getFlat().getRoom());

Исходя из этого можно предположить, что есть изначально некий список городов из которого берется только 1, уже на основе этого города берется определенная улица итд. Это так работает?

Это псевдокод. То есть код, который может реально не работать, а используется лишь для демонстрации какой-то идеи

Предположения неверные.

Это всего лишь вызовы методов, и ничего кроме наличия таких методов, совместимости вызовов по типам объектов к которым они применяются, и того, что последний объект должен иметь метод, обеспечивающий работу print(), оно не предполагает.

Методы getЧто-то() традиционно предназначены вообще, как я читал, именно для инкапсуляции, скрытия реализации данных и кода от пользователя. Вы можете не знать (и не должны, в общем случае, знать), что внутри и как работает этот getЧто-то(), вы знаете только что и какого типа он может вам вернуть.

(поправьте меня более знающие товарищи, если прочитанное где-то ввело меня в заблуждение)

Как ты сам представляешь метод getCity() может вернуть тебе 1 город из списка? Именно тот, который нужен. Магии ведь не существует :smile:

Короче, ты сделал неверные выводы на основе недостаточности информации. Это работает не так. А как это работает, выше уже написали: предыдущий вызов в цепочке возвращает объект, метод которого вызывается следующим. Всё просто. Никакой магии

Я думаю, тут нужны более подробные пояснения.
Метод getCity() не имеет параметров, то есть в нём нет никакого указания на то, что вообще существует какой-то список, тем более индексированный.

В таком стиле называются методы типа getter, назначение которых в выдаче по запросу какой-то информации об объекте.

Допустим, есть объект “Address”, у которого могут быть поля Country , City, Street, … и т.д… а может и не быть вообще полей, а быть связь с какой-то базой данных.

getCity() выдает город без уточнения где он его берёт и какие процедуры надо выполнять с тем, что берётся, до выдачи (допустим, тому, кто использует объект, не обязательно знать, что город может быть взят из базы данных и “расшифрован” ибо в базе данные хранятся в зашифрованном виде).

Но используя геттеры мы возвращаем переменную, для которой было ранее установлено значение. А для реализации “Последовательного вызова методов” нам нужно вернуть класс в котором есть следующий метод, разве нет? Я просто не пойму, в таком методе, каждый метод существует сам по себе?

Но используя геттеры мы возвращаем переменную, для которой было ранее установлено значение.

Почему обязательно переменную? Класс может включать другие классы, и в возвращении методом одного класса другого класса нет ничего крамольного.

Я просто не пойму, в таком методе, каждый метод существует сам по себе?

Есть объекты и методы. Как я уже описал выше,
Объект 1 - Метод 1
Объект 2 - Метод 2
Объект 3 - Метод 3
Всё.

Указанный сложный вызов может описывать “матрёшечный” объект, в котором внутри класса Город класс Улица и метод вернутьУлицу, внутри класса Улица есть класс Дом и метод вернутьДом и т.д.
“В зайце утка, в утке яйцо, в яйце игла, а в игле смерть Кощеева”
А что пример искусственный, ну так правильно выше сказали, на то он и пример.

Спасибо. После фразы матрешка, что-то прояснилось, скорее главное сейчас попробовать это на практике.

Попробую внести еще немного “тумана” в данный вопрос. Помимо “матрешечного” варианта, объект может возвращать и самого себя

class A{
  public A print(){
    System.out.println("Hello!");
    return this;
  }
}
new A().print().print().print().print().print().print();

Спасибо за ответы, теперь стало понятно и уже во всю экспериментирую. =)

Может-то он может :slight_smile: Но если возвращает себя, то в чём тогда смысл вызова “цепочкой” getter’ов вместо вызова всего одного из них? :smile: Как по мне, то если возвращает себя, логика такой цепочки getter’ов теряется.

А кто сказал, что рассматриваются только геттеры?

new Actions(driver).moveToElement(el).clickAndhold().moveByOffset(10,10).release().perform();

new MyPage().fill(data).save().verify(data).close();

Тут кажется , что нужно понять, что следующий метод работает только с возвращаемым значением. Что реально произошло в предыдущем - следующий не знает. Да и его это мало волнует. Ему важно, чтобы у него был нужный объект с нужными ему данными(если внутри него какая-то логика зашита с этими данными)

Это как когда вы приходите в магазин за молоком. магазин(как объект) может вернуть вам молоко. Вы делаете из него коктейль и передаете дальше. Ни вам неизвестно, как магазин получил молоко, и получающему коктейль неизвестно (да и не важно) - как вы сделали коктейль. Каждому важен лишь получаемый им объект. А что произошло для получения этого объекта - остается неизвестным.

Вчера когда пробовал “матрешечный” стиль =) Наткнулся попутно в книге “Совершенный код”, что такой стиль кроет в себе и палки. Если ты вызываешь следующий метод не связанный с предыдущим. И действительно когда я посмотрел какие методы у меня доступны, оказалась полная белиберда (доступны были методы не характерные для определенной страницы). Я ведь правильно понимаю, что следующий вызов метода должен все же не нарушать логическую связь с предыдущим и чтобы у пользователя не было доступа к лишним методам?

Последовательность задаете вы сами, посему и ответственность за возвращаемый тип / логику / построение связей лежит на вас. Но в случае наследования от абстрактной пейджи, вам в любом случае IntelliSense будет выдавать список доступных методов как текущей страницы, так и родителя(-ей). Но, к примеру, IntelliJ IDEA при этом выделяет жирным шрифтом методы доступные в пределах текущего класса.

1 Симпатия

Ты лучше покажи что там за матрешечный стиль. А-то “на пальцах” каждый по-своему понимает. Я так понял, что ты вложенные классы мутишь