Здравствуйте, у меня sonar начал ругаться на сложность кода и его надо уменьшить его с 17 к 15, и я решил разбить метод на несколько маленьких,

Но пока я не знаю как это правильно сделать и с чего начать, и мне кажется плохая читаемость из-за while (!allCoords.isEmpty()) { так как он затрагивает весь метод, можно ли его как то порефакторить?

@Override
    public List<GroupedOrderDto> getClusteredCoords(double distance, int litres) {
        checkIfSpecifiedLitresAndDistancesAreValid(distance, litres);
        Set<Coordinates> allCoords = addressRepository.undeliveredOrdersCoordsWithCapacityLimit(litres);
        List<GroupedOrderDto> allClusters = new ArrayList<>();

        while (!allCoords.isEmpty()) {
            Optional<Coordinates> any = allCoords.stream().findAny();
            any.ifPresent(coordinates -> {
                Coordinates currentlyCoord = coordinates;

                Set<Coordinates> closeRelatives = getCoordinateCloseRelatives(distance,
                    allCoords, currentlyCoord);
                Coordinates centralCoord = getNewCentralCoordinate(closeRelatives);

                while (!centralCoord.equals(currentlyCoord)) {
                    currentlyCoord = centralCoord;
                    closeRelatives = getCoordinateCloseRelatives(distance, allCoords, currentlyCoord);
                    centralCoord = getNewCentralCoordinate(closeRelatives);
                }
                int amountOfLitresInCluster = 0;
                for (Coordinates current : closeRelatives) {
                    int currentCoordinatesCapacity =
                        addressRepository.capacity(current.getLatitude(), current.getLongitude());
                    amountOfLitresInCluster += currentCoordinatesCapacity;
                }

                if (amountOfLitresInCluster > litres) {
                    List<Coordinates> closeRelativesSorted = new ArrayList<>(closeRelatives);
                    closeRelativesSorted.sort(getComparatorByDistanceFromCenter(centralCoord));
                    int indexOfCoordToBeDeleted = -1;
                    while (amountOfLitresInCluster > litres) {
                        Coordinates coordToBeDeleted = closeRelativesSorted.get(++indexOfCoordToBeDeleted);
                        int anountOfLitresInCurrentOrder = addressRepository
                            .capacity(coordToBeDeleted.getLatitude(), coordToBeDeleted.getLongitude());
                        amountOfLitresInCluster -= anountOfLitresInCurrentOrder;
                        closeRelatives.remove(coordToBeDeleted);
                    }
                }

                for (Coordinates grouped : closeRelatives) {
                    allCoords.remove(grouped);
                }

                // mapping coordinates to orderDto
                getUndeliveredOrdersByGroupedCoordinates(closeRelatives,
                    amountOfLitresInCluster, allClusters);
            });
        }
        return allClusters;
    }

Ответы (1 шт):

Автор решения: Yevhen Bufan

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

@Override
        public List<GroupedOrderDto> getClusteredCoords(double distance, int litres) {
            checkIfSpecifiedLitresAndDistancesAreValid(distance, litres);
            Set<Coordinates> allCoords = addressRepository.undeliveredOrdersCoordsWithCapacityLimit(litres);
            List<GroupedOrderDto> allClusters = new ArrayList<>();
    
            while (!allCoords.isEmpty()) {
                Optional<Coordinates> any = allCoords.stream().findAny();
                mainBlockOfGetClusteredCoords(allCoords, distance, litres, any, allClusters);
            }
            return allClusters;
        }
    
        private void mainBlockOfGetClusteredCoords(Set<Coordinates> allCoords, double distance,
            int litres, Optional<Coordinates> any, List<GroupedOrderDto> allClusters) {
            any.ifPresent(coordinates -> {
                Coordinates currentlyCoord = coordinates;
    
                Set<Coordinates> closeRelatives = getCoordinateCloseRelatives(distance,
                    allCoords, currentlyCoord);
                Coordinates centralCoord = getNewCentralCoordinate(closeRelatives);
    
                while (!centralCoord.equals(currentlyCoord)) {
                    currentlyCoord = centralCoord;
                    closeRelatives = getCoordinateCloseRelatives(distance, allCoords, currentlyCoord);
                    centralCoord = getNewCentralCoordinate(closeRelatives);
                }
                int amountOfLitresInCluster = 0;
                for (Coordinates current : closeRelatives) {
                    int currentCoordinatesCapacity =
                        addressRepository.capacity(current.getLatitude(), current.getLongitude());
                    amountOfLitresInCluster += currentCoordinatesCapacity;
                }
                if (amountOfLitresInCluster > litres) {
                    List<Coordinates> closeRelativesSorted = new ArrayList<>(closeRelatives);
                    closeRelativesSorted.sort(getComparatorByDistanceFromCenter(centralCoord));
                    int indexOfCoordToBeDeleted = -1;
    
                    while (amountOfLitresInCluster > litres) {
                        Coordinates coordToBeDeleted = closeRelativesSorted.get(++indexOfCoordToBeDeleted);
                        int anountOfLitresInCurrentOrder = addressRepository
                            .capacity(coordToBeDeleted.getLatitude(), coordToBeDeleted.getLongitude());
                        amountOfLitresInCluster -= anountOfLitresInCurrentOrder;
                        closeRelatives.remove(coordToBeDeleted);
                    }
                }
                for (Coordinates grouped : closeRelatives) {
                    allCoords.remove(grouped);
                }
    
                // mapping coordinates to orderDto
                getUndeliveredOrdersByGroupedCoordinates(closeRelatives,
                    amountOfLitresInCluster, allClusters);
            });
        }
→ Ссылка