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


(rpwheeler) #4

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


(Alex) #5

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

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

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


(Александр Таранков) #6

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


(rpwheeler) #7

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

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

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

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


(Александр Таранков) #8

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

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


(rpwheeler) #9

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

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

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

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


(Alex) #10

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


(rpwheeler) #11

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

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

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

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

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


(Alex) #12

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


(vmaximv) #13

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

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

new A().print().print().print().print().print().print();

(Alex) #14

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


(rpwheeler) #15

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


(vmaximv) #16

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


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


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


(sidelnikovmike) #17

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

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


(Alex) #18

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


(Sergey Korol) #19

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


Оптимизация Framework или одинаковый функционал на некоторых страницах
(Александр Таранков) #20

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


(Alex) #21

Все верно, в одной из тем мне говорили о плохом коде. Поэтому я решил переписать все на подобный стиль.


(Alex) #22

Хотелось бы спросить правильно ли выполнять следующее. Например есть домашняя страница и страница с формой, у нее есть возможность "сохранить и вернуться на домашнюю страницу" и "Сохранить и остаться на главной форме". Например когда мы возвращаемся на главную страницу я думаю разумно было выполнять ее инициализацию:

public HomePage saveAndClose() {
		saveAndClose.click();
		return PageFactory.initElements(driver, HomePage.class);
				
	}

...
public void test{
...
HomePage homepage = karaoke.setName("asd").clickSaveAndClose();
homepage.verifyCard("asd") // проверяем добавилась ли карточка
...
}

А если мы просто нажмем сохранение и останемся на форме, опять же нужно делать инициализацию этой же страницы?


(Александр Таранков) #23

Это уже оффтоп, заводи новую тему, там будем разбирать