Elementor Header #8

33. Цепочки вызовов методов

1. Введение

Цепочки вызовов методов — это техника, которая позволяет вызывать несколько методов последовательно на одном и том же объекте. Это улучшает читаемость кода и делает его более компактным. В этом уроке мы рассмотрим, как создавать и использовать цепочки вызовов методов, и изучим распространённые ошибки, которые могут возникнуть при их использовании.

2. Что такое цепочки вызовов методов

Цепочка вызовов методов (Method Chaining) — это подход, при котором несколько методов вызываются последовательно, один за другим. Для реализации цепочки вызовов методов методы должны возвращать ссылку на текущий объект (обычно this), что позволяет продолжать вызовы других методов на том же объекте.

Пример без цепочки вызовов:

				
					public class Person {
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person();
        person.setName("John");
        person.setAge(30);
    }
}

				
			

Пример с цепочкой вызовов:

				
					public 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 class Main {
    public static void main(String[] args) {
        Person person = new Person()
            .setName("John")
            .setAge(30);
    }
}

				
			

В этом примере методы setName и setAge возвращают текущий объект (this), что позволяет вызывать их в цепочке.

3. Преимущества цепочек вызовов

Использование цепочек вызовов методов имеет несколько преимуществ:

  1. Повышение читаемости: Цепочки позволяют создавать более компактный и легко читаемый код, особенно при настройке объектов.
  2. Удобство: Возможность последовательно настраивать объект уменьшает количество промежуточных переменных.
  3. Снижение количества кода: Цепочки могут сократить количество строк кода, так как можно избежать повторных обращений к одному и тому же объекту.

4. Пример использования цепочек вызовов

Цепочки вызовов часто используются в паттерне «строитель» (Builder Pattern), который позволяет создавать сложные объекты пошагово.

Пример построения объекта с помощью цепочки вызовов:

				
					public class Car {
    private String make;
    private String model;
    private int year;

    public Car setMake(String make) {
        this.make = make;
        return this;
    }

    public Car setModel(String model) {
        this.model = model;
        return this;
    }

    public Car setYear(int year) {
        this.year = year;
        return this;
    }

    @Override
    public String toString() {
        return "Car{" +
               "make='" + make + '\'' +
               ", model='" + model + '\'' +
               ", year=" + year +
               '}';
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car()
            .setMake("Toyota")
            .setModel("Corolla")
            .setYear(2020);

        System.out.println(car);
    }
}

				
			

Вывод:

				
					Car{make='Toyota', model='Corolla', year=2020}

				
			

5. Создание цепочек в собственных классах

Для создания цепочек вызовов в своих классах нужно убедиться, что методы возвращают текущий объект (обычно с помощью return this;).

Пример:

				
					public class Rectangle {
    private int length;
    private int width;

    public Rectangle setLength(int length) {
        this.length = length;
        return this;
    }

    public Rectangle setWidth(int width) {
        this.width = width;
        return this;
    }

    public int calculateArea() {
        return this.length * this.width;
    }
}

public class Main {
    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle()
            .setLength(10)
            .setWidth(5);

        int area = rectangle.calculateArea();
        System.out.println("Area: " + area); // Вывод: Area: 50
    }
}

				
			

6. Распространённые ошибки и их исправление

6.1. Ошибка: Неправильный тип возвращаемого значения

Если метод в цепочке не возвращает текущий объект, цепочка вызовов прервётся.

Ошибка:

				
					public class Person {
    private String name;

    public void setName(String name) { // Возвращаемый тип void
        this.name = name;
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person()
            .setName("John") // Ошибка: метод не возвращает объект, цепочка прервётся
            .setAge(30); // Следующий метод не может быть вызван
    }
}

				
			

Исправление:

Измените возвращаемый тип метода на тип класса.

				
					public Person setName(String name) {
    this.name = name;
    return this;
}

				
			

6.2. Ошибка: Возврат нового объекта вместо текущего

Если метод в цепочке возвращает новый объект, это может привести к непредсказуемым результатам.

Ошибка:

				
					public class Person {
    private String name;

    public Person setName(String name) {
        this.name = name;
        return new Person(); // Ошибка: возвращается новый объект
    }
}

				
			

Исправление:

Всегда возвращайте текущий объект, используя this.

				
					public Person setName(String name) {
    this.name = name;
    return this; // Правильное решение
}

				
			

Заключение

Цепочки вызовов методов — это мощная техника, которая улучшает читаемость и удобство использования кода, позволяя легко настраивать объекты и вызывать методы последовательно. Однако важно следить за тем, чтобы методы в цепочке возвращали правильный объект, чтобы избежать ошибок.

7. Тестовое задание

Напишите класс Laptop, который позволяет настраивать следующие параметры с использованием цепочек вызовов методов:

  • Модель (model)
  • Производитель (brand)
  • Количество оперативной памяти (ram)
  • Объём жесткого диска (storage)

Пример использования:

				
					Laptop laptop = new Laptop()
    .setModel("XPS 13")
    .setBrand("Dell")
    .setRam(16)
    .setStorage(512);

System.out.println(laptop);

				
			

Ожидаемый результат:

				
					Laptop{model='XPS 13', brand='Dell', ram=16, storage=512}

				
			

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

logo