> For the complete documentation index, see [llms.txt](https://letas-organization.gitbook.io/letaats-lessons-online/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://letas-organization.gitbook.io/letaats-lessons-online/kolledzh-top/razdel-1/glava-12.-metody-i-dekompoziciya.md).

# Глава 12. Методы и декомпозиция

### 12.1. Почему нельзя писать всё в main

На первых занятиях удобно писать весь код в `main`.

```java
public class Main {
    public static void main(String[] args) {
        // весь код здесь
    }
}
```

Для маленькой задачи это нормально.

Но если программа становится больше, `main` превращается в свалку:

```
ввод
проверки
циклы
расчёты
вывод
меню
поиск
сортировка
ещё один ввод
ещё один вывод
```

Такой код трудно читать, проверять и исправлять.

Методы нужны, чтобы разделить программу на части.

***

### 12.2. Что такое метод

Метод — это именованный блок кода, который выполняет конкретную задачу.

Пример:

```java
public static void sayHello() {
    System.out.println("Hello");
}
```

Вызов метода:

```java
sayHello();
```

***

### 12.3. Метод без параметров

```java
public static void printMenu() {
    System.out.println("1 — добавить");
    System.out.println("2 — показать");
    System.out.println("3 — выйти");
}
```

Такой метод всегда делает одно и то же: выводит меню.

***

### 12.4. Метод с параметрами

Параметры позволяют передавать данные в метод.

```java
public static void printName(String name) {
    System.out.println("Имя: " + name);
}
```

Вызов:

```java
printName("Anna");
```

Значение `"Anna"` попадает в параметр `name`.

***

### 12.5. Параметр и аргумент

Параметр — переменная в объявлении метода.

```java
public static void printName(String name)
```

`name` — параметр.

Аргумент — конкретное значение при вызове.

```java
printName("Anna");
```

`"Anna"` — аргумент.

***

### 12.6. Метод с return

Если метод должен вернуть результат, используется `return`.

```java
public static int sum(int a, int b) {
    return a + b;
}
```

Вызов:

```java
int result = sum(5, 10);
```

Метод вернул `15`, и это значение записалось в `result`.

***

### 12.7. void

`void` означает, что метод ничего не возвращает.

```java
public static void printHello() {
    System.out.println("Hello");
}
```

Такой метод просто выполняет действие.

***

### 12.8. return завершает метод

```java
public static int checkAge(int age) {
    if (age < 0) {
        return 0;
    }

    return age;
}
```

Если `age < 0`, метод вернёт `0` и завершится. Код ниже уже не будет выполняться.

***

### 12.9. Метод для суммы массива

```java
public static int getSum(int[] numbers) {
    int sum = 0;

    for (int i = 0; i < numbers.length; i++) {
        sum += numbers[i];
    }

    return sum;
}
```

Использование:

```java
int[] arr = {1, 2, 3};
int result = getSum(arr);

System.out.println(result);
```

***

### 12.10. Метод для максимума

```java
public static int getMax(int[] numbers) {
    int max = numbers[0];

    for (int i = 1; i < numbers.length; i++) {
        if (numbers[i] > max) {
            max = numbers[i];
        }
    }

    return max;
}
```

***

### 12.11. Метод для проверки чётности

```java
public static boolean isEven(int number) {
    return number % 2 == 0;
}
```

Использование:

```java
if (isEven(10)) {
    System.out.println("Чётное");
}
```

Такой код читается почти как обычный текст.

***

### 12.12. Декомпозиция

Декомпозиция — разбиение большой задачи на маленькие подзадачи.

Пример задачи: программа анализирует оценки.

Без декомпозиции:

```
main:
- ввод оценок
- сумма
- среднее
- максимум
- минимум
- вывод
```

С декомпозицией:

```
inputGrades()
getSum()
getAverage()
getMax()
getMin()
printResult()
```

Каждый метод отвечает за свою задачу.

***

### 12.13. Пример плохого кода

```java
public class Main {
    public static void main(String[] args) {
        int[] grades = {5, 4, 3, 5};

        int sum = 0;
        for (int i = 0; i < grades.length; i++) {
            sum += grades[i];
        }

        double avg = (double) sum / grades.length;

        int max = grades[0];
        for (int i = 1; i < grades.length; i++) {
            if (grades[i] > max) {
                max = grades[i];
            }
        }

        System.out.println("Среднее: " + avg);
        System.out.println("Максимум: " + max);
    }
}
```

Код работает, но вся логика лежит в `main`.

***

### 12.14. Тот же код с методами

```java
public class Main {

    public static int getSum(int[] grades) {
        int sum = 0;

        for (int i = 0; i < grades.length; i++) {
            sum += grades[i];
        }

        return sum;
    }

    public static double getAverage(int[] grades) {
        return (double) getSum(grades) / grades.length;
    }

    public static int getMax(int[] grades) {
        int max = grades[0];

        for (int i = 1; i < grades.length; i++) {
            if (grades[i] > max) {
                max = grades[i];
            }
        }

        return max;
    }

    public static void main(String[] args) {
        int[] grades = {5, 4, 3, 5};

        System.out.println("Среднее: " + getAverage(grades));
        System.out.println("Максимум: " + getMax(grades));
    }
}
```

Теперь `main` стал короче и понятнее.

***

### 12.15. Почему методы делают код лучше

Методы помогают:

* уменьшить повторение кода;
* сделать программу понятнее;
* переиспользовать логику;
* легче тестировать;
* легче исправлять ошибки.

Если метод `getAverage()` работает неправильно, нужно проверять именно его, а не весь `main`.

***

### 12.16. Перегрузка методов

Перегрузка — несколько методов с одним именем, но разными параметрами.

```java
public static int sum(int a, int b) {
    return a + b;
}

public static double sum(double a, double b) {
    return a + b;
}
```

Java выбирает подходящий метод по типам аргументов.

***

### 12.17. Имена методов

Имя метода должно описывать действие.

Плохо:

```java
public static int doSomething(int[] arr)
```

Лучше:

```java
public static int getMax(int[] arr)
```

Хорошие имена:

```java
printMenu()
getAverage()
findMax()
isEven()
countPositive()
```

***

### 12.18. Методы и Android

В Android методы нужны постоянно.

Например, можно вынести проверку ввода:

```java
private boolean isInputEmpty(String text) {
    return text.isEmpty();
}
```

Или вычисление:

```java
private double convertRubToUsd(double rub) {
    return rub / 90;
}
```

Тогда в обработчике кнопки будет меньше кода.

Плохо:

```java
button.setOnClickListener(v -> {
    // 100 строк логики
});
```

Лучше:

```java
button.setOnClickListener(v -> {
    handleButtonClick();
});
```

И отдельно:

```java
private void handleButtonClick() {
    // логика обработки
}
```

***

### 12.19. Service-классы: подготовка к следующему уровню

Когда методов становится много, их можно выносить в отдельные классы.

Например:

```java
class GradeService {
    public int getSum(int[] grades) {
        int sum = 0;

        for (int grade : grades) {
            sum += grade;
        }

        return sum;
    }

    public double getAverage(int[] grades) {
        return (double) getSum(grades) / grades.length;
    }
}
```

Использование:

```java
GradeService service = new GradeService();
double avg = service.getAverage(grades);
```

Это уже похоже на нормальную структуру приложения:

```
Main — запуск
Service — логика
Model — данные
```

***

### 12.20. Типичные ошибки новичков

#### Ошибка 1. Забыть вызвать метод

```java
public static void hello() {
    System.out.println("Hello");
}
```

Метод создан, но не вызван.

Нужно:

```java
hello();
```

***

#### Ошибка 2. Метод должен вернуть значение, но return нет

```java
public static int sum(int a, int b) {
    int result = a + b;
}
```

Ошибка: метод обещал вернуть `int`.

Правильно:

```java
public static int sum(int a, int b) {
    return a + b;
}
```

***

#### Ошибка 3. Путать void и return

Если метод `void`, он ничего не возвращает.

```java
public static void printHello() {
    return "Hello"; // ошибка
}
```

***

#### Ошибка 4. Делать метод слишком большим

Если метод занимает 100 строк и делает всё подряд, это уже почти новый `main`, просто переодетый. Пользы мало.

***

### 12.21. Как могут спросить на экзамене

#### Вопрос

Что такое метод?

#### Хороший ответ

> Метод — это именованный блок кода, который выполняет определённую задачу. Метод может принимать параметры и возвращать результат через `return`.

***

#### Вопрос

Что такое параметр метода?

#### Хороший ответ

> Параметр — это переменная, указанная в объявлении метода, через которую метод получает данные для работы.

***

#### Вопрос

Что делает `return`?

#### Хороший ответ

> `return` возвращает значение из метода и завершает выполнение метода.

***

#### Вопрос

Что такое декомпозиция?

#### Хороший ответ

> Декомпозиция — это разбиение большой задачи на маленькие части. В программировании это помогает выносить отдельные действия в методы или классы.

***

### 12.22. Практические задания

#### Задание 1

Напишите метод:

```java
public static int square(int x)
```

Он должен возвращать квадрат числа.

***

#### Задание 2

Напишите метод:

```java
public static boolean isAdult(int age)
```

Он должен возвращать `true`, если возраст 18 или больше.

***

#### Задание 3

Напишите метод для суммы массива.

***

#### Задание 4

Напишите метод для поиска максимума массива.

***

#### Задание 5

Напишите метод для подсчёта чётных чисел в массиве.

***

#### Задание 6

Напишите метод, который принимает строку и возвращает её длину.

***

#### Задание 7

Напишите программу анализа оценок, разбив её на методы:

* `getSum`;
* `getAverage`;
* `getMax`;
* `getMin`.

***

#### Задание 8

Создайте меню программы, а вывод меню вынесите в отдельный метод `printMenu()`.

***

### 12.23. Мини-проект главы: анализатор оценок

Задача: создать программу, которая анализирует оценки студента.

Функции:

* вывести все оценки;
* найти средний балл;
* найти максимальную оценку;
* найти минимальную оценку;
* посчитать количество двоек.

Пример структуры:

```java
public class Main {

    public static void printGrades(int[] grades) {
        for (int grade : grades) {
            System.out.println(grade);
        }
    }

    public static int getSum(int[] grades) {
        int sum = 0;

        for (int grade : grades) {
            sum += grade;
        }

        return sum;
    }

    public static double getAverage(int[] grades) {
        return (double) getSum(grades) / grades.length;
    }

    public static int getMax(int[] grades) {
        int max = grades[0];

        for (int grade : grades) {
            if (grade > max) {
                max = grade;
            }
        }

        return max;
    }

    public static int countBadGrades(int[] grades) {
        int count = 0;

        for (int grade : grades) {
            if (grade == 2) {
                count++;
            }
        }

        return count;
    }

    public static void main(String[] args) {
        int[] grades = {5, 4, 3, 2, 5};

        printGrades(grades);

        System.out.println("Средний балл: " + getAverage(grades));
        System.out.println("Максимальная оценка: " + getMax(grades));
        System.out.println("Количество двоек: " + countBadGrades(grades));
    }
}
```

***

### 12.24. Вопросы для самопроверки

1. Что такое метод?
2. Зачем нужны методы?
3. Что такое параметр?
4. Что такое аргумент?
5. Что делает `return`?
6. Что означает `void`?
7. Можно ли вызвать метод несколько раз?
8. Что такое декомпозиция?
9. Почему плохо писать всю программу в `main`?
10. Как методы помогают в Android-разработке?
11. Что такое перегрузка методов?
12. Как правильно называть методы?
13. Что такое service-класс?
14. Почему метод должен выполнять одну понятную задачу?
15. Как вынести логику из обработчика кнопки в Android?

***

## Итог по главам 9–12

После этих глав вы должны уметь:

* писать циклы `for` и `while`;
* понимать, что такое итерация;
* использовать `break` и `continue`;
* писать циклы для суммы и подсчёта;
* создавать массивы;
* работать с индексами;
* заполнять массив через Scanner;
* находить сумму, максимум, минимум и среднее;
* понимать базовые алгоритмы;
* писать методы;
* использовать параметры и `return`;
* делить программу на части;
* понимать, почему нельзя держать всю логику в `main`.

Следующий блок: классы, объекты, конструкторы, `this`, инкапсуляция и основы ООП.
