Страницы

Поиск по вопросам

четверг, 12 декабря 2019 г.

Method chaining в Java - что это, и с чем его едят?

#java


Объясните, как оно живет и как с ним работать? 

Имеется в виду следующее явление:

Strings
    .emptyToNull(sector))
    .stream()
    .map(ClientCompany::fromCompany)
    .collect(Collectors.toList());

    


Ответы

Ответ 1



Цитата из статьи Википедии Method chaining Method chainig (цепочки) - общее название синтаксиса в ООП, в котором несколько методов вызываются один за другим. Там же есть простой пример кода на Java: class Person { private String name; private int age; public Person setName(String name) { this.name = name; return this; // Возвращаем объект } public Person setAge(int age) { this.age = age; return this; // Возвращаем объект } public void introduce() { System.out.println("Hello, my name is " + name + " and I am " + age + " years old."); } // Использование: public static void main(String[] args) { Person person = new Person(); // Output: Hello, my name is Peter and I am 21 years old. person.setName("Peter") .setAge(21) .introduce(); // Вызываем методы цепочкой (Method chaining) } } Вся идея в том, чтобы сделать так, чтобы методы вызывались один за другим. Для этого нужно, чтобы каждый предыдущий метод возвращал такое значение, которое нужно следующему. Как конструктор Lego. Структуру можно делать очень разную, вплоть до вложенных(nested) классов. Можно выделить то, что использование такого синтаксиса экономит время. Не считаю, что это стоит использовать часто. Такие классы по мере возрастания сложности становятся нечитабельными. Это стоит использовать только тогда, когда без этого очень долго.

Ответ 2



В Java оно ничем не отличается от других языков программирование. Вся идея method chaining сводится к простому правилу: Методы должны возвращать объекты. Это могут быть абсолютно любые объекты - как относящиеся к классу или родителям класса содержащего метод, так и нет. Просто по выходу из метода всегда возвращайте объект. Будете применять это правило - сможете организовывать довольно приятные глазу цепочки из операций, наподобие этой: player .takeRevolver() .loadBullet() .rotateCylinder() .putToHead() .shoot(); Вместо субъективно менее приятного: Revolver revolver = new Revolver(player); revolver.loadBullet(); revolver.rotateCylinder(); revolver.putToHead(); revolver.shoot(); Также на базе идеи method chaining'а, существует идея о fluent interface, суть которой сводится к: Методы должны возвращать объект, к которому они относятся. Это позволяет создавать довольно приятные глазу программные интерфейсы "построителей", предполагающие многошаговую настройку создаваемых объектов: Car car = CarBuilder:create() .setEngine(new Engine(FuelType::GAZOLINE, 1.5)) .setExterior(Colors::BLACK_MATTE) .setInterior(Materials::GRAY_FABRIC) .setAbs(new Abs(4, 4)) .setNeon(Colors::PURPLE) .build()

Ответ 3



На хабре, на мой взгляд, есть хорошая статья на эту тему. Правда там рассматривается его реализация на С++, но на сколько я понимаю, этот прием применим и к java. Так же ссылка от @LEQADA на англоязычную статью в википедии присутствует, жаль что нет на русском

Ответ 4



Кроме достоинств в "method chaining" есть и недостатки. Код не всегда будет выглядеть достаточно наглядно для понимания при иерархии наследования. Вот пример: package chain; class A { public A chainedMethod() { System.out.println(" chainedMethod() in class A"); return this; } } class B extends A { @Override public A chainedMethod() { System.out.println(" chainedMethod() in class B"); return this; } public void doStuff() { System.out.println(" doStuff() in B"); } } public class D extends B { public static void main(String[] args) { // (new B().chainedMethod()).doStuff();// ошибка - здесь попытка вызвать метод //класса A ((B) new B().chainedMethod()).doStuff(); // так работает } } То есть код не будет работать без явного приведения типа. Дополнительные приведения типов сделают код трудночитаемым.

Комментариев нет:

Отправить комментарий