Как уменьшить вложенность кода

90
27 ноября 2021, 06:40

У меня есть такой метод. Но у него слишком высокая вложенность. Подскажите, как её уменьшить. Мне посоветовали Stream, но никак не могу придумать как его впихнуть именно для уменьшения вложенности.

    public static List<Room> loadRooms() {
            List<Room> rooms = new ArrayList<>();
            File dir = new File(DEFAULT_ROOM_PATH);
            File[] arrFiles = dir.listFiles((dir1, name) -> name.endsWith(".json"));
            if (arrFiles == null) {
                System.out.println("Nothing rooms to load.");
            } else {
                List<File> lst = Arrays.asList(arrFiles);
                for (File file : lst) {
                    System.out.println(file.getName());
                }
                Scanner scanner = new Scanner(System.in);
                System.out.print("Enter room id or 'all' to load: ");
                String input = scanner.nextLine();
                if (input.toLowerCase().equals("all")) {
                    for (File file : lst) {
                        try (FileReader reader = new FileReader(DEFAULT_ROOM_PATH + file.getName())) {
                            Room room = new Gson().fromJson(reader, Room.class);
                            rooms.add(room);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                } else {
                    int id = Integer.parseInt(input);
                    String fileName = id + ".json";
                    File loadFile = lst.stream().filter(file -> file.getName().equals(fileName)).findFirst().orElse(null);
                    if (loadFile == null) {
                        System.out.println("Nothing found");
                    } else {
                        try (FileReader reader = new FileReader(DEFAULT_ROOM_PATH + loadFile.getName())) {
                            Room room = new Gson().fromJson(reader, Room.class);
                            rooms.add(room);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            return rooms;
        }
Answer 1

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

public static List<Room> loadRooms() {
    List<Room> rooms = new ArrayList<>();
    File dir = new File(DEFAULT_ROOM_PATH);
    File[] arrFiles = dir.listFiles((dir1, name) -> name.endsWith(".json"));
    if (arrFiles != null) {
       processArrFiles()
    }
    return rooms;
}
private static List<Room> getRooms(String input){
   if (input.toLowerCase().equals("all")) {
     rooms = loadAllRooms(lst); //это ветвление выносим в отдельный метод
   } else {
     rooms = loadSomeRooms(input); //это тоже 
   }
}
void processArrFiles(){
        List<File> lst = Arrays.asList(arrFiles);
        //заменил на лямбду, просто немного меньше фигурных скобок, вкусовщина :)
        lst.forEach(file -> System.out.println(file.getName()));
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter room id or 'all' to load: ");
        String input = scanner.nextLine();
        rooms = getRooms(input);
  }

ну это как демонстрация идеи

Answer 2

Проблема тут не только во вложенности, а и в том, что метод делает слишком много разных вещей. Его нужно разделить, тогда и вложенность сама собой распадется. Я немного отрефакторил, это всё еще далеко от идеала, так как для значительных улучшений нужно переписывать саму логику, однако вложенность немного растаяла :)

public static List<Room> loadRooms() {
        List<Room> rooms = new ArrayList<>();
        File dir = new File(DEFAULT_ROOM_PATH);
        File[] arrFiles = dir.listFiles((dir1, name) -> name.endsWith(".json"));
        //если arrFiles == null, вернется пустой список, логика та же, вложенность меньше
        if (arrFiles != null) {
            List<File> lst = Arrays.asList(arrFiles);
            //заменил на лямбду, просто немного меньше фигурных скобок, вкусовщина :)
            lst.forEach(file -> System.out.println(file.getName()));
            Scanner scanner = new Scanner(System.in);
            System.out.print("Enter room id or 'all' to load: ");
            String input = scanner.nextLine();
            if (input.toLowerCase().equals("all")) {
                rooms = loadAllRooms(lst); //это ветвление выносим в отдельный метод
            } else {
                rooms = loadSomeRooms(input); //это тоже 
            }
        }
        return rooms;
    }
READ ALSO
Как создать музыкальный плеер на Java?

Как создать музыкальный плеер на Java?

есть идея создать музыкальный плеер на Java/SwingСуть будет вот в чем: 1)Можно будет проигрывать музыку на локальной машине

173
Как будет работать программа?

Как будет работать программа?

Подскажите, пожалуйста, зачем так пишут и как будет работать программа?

182
Чтение DBF в Java

Чтение DBF в Java

Есть DBF файл с определенным набором полейЗаписей в таблице около 50 тысяч

226
Сортировка списка данных из bd java

Сортировка списка данных из bd java

Есть вот такой кодОн выбирает из базы данные за 24 часа

161