在一个方法中重构函数重载方法

Refactor function overloaded methods in just one method

目前我有一个重载以下方法的方法:

    public boolean isHorizontalOrVertical(Point firstPoint, Point secondPoint) {
        return firstPoint.getFirstComponent() == secondPoint.getFirstComponent()
                || firstPoint.getSecondComponent() == secondPoint.getSecondComponent();
    }

    public boolean isHorizontalOrVertical(List<Point> points) {
        if (points == null || points.size() < 2) {
            throw new IllegalArgumentException("invalid number of points");
        }
        Point start = points.get(0);
        return points.stream()
                .allMatch(p -> isHorizontalOrVertical(start, p));
    }

需要该方法来检查两个或三个点是否vertical/horizontal彼此。在三个点的情况下,它只需要检查最后两个点是否 horizontal/vertical 到起点。

有谁知道我怎样才能将所有内容都集中到一种方法中?

方法可以这样实现:

public boolean isHorizontalOrVertical(Point firstPoint, Point secondPoint, Point thirdPoint) {
    return isHorizontalOrVertical(Arrays.asList(firstPoint, secondPoint, thirdPoint));
}

当列表为空时,您的 isHorizontalOrVertical(List<Point>) 方法将失败,当列表只有一个元素时,调用没有多大意义。

我认为更好的方法是使用两个必需的参数,加上一个可变参数,这样调用者至少必须给 2 分。

private boolean are2PointsHorizontalOrVertical(Point firstPoint, Point secondPoint) {
    return firstPoint.getFirstComponent() == secondPoint.getFirstComponent()
            || firstPoint.getSecondComponent() == secondPoint.getSecondComponent();
}

public boolean arePointsHorizontalOrVertical(Point point1, Point point2, Point... rest) {
    return are2PointsHorizontalOrVertical(point1, point2) &&
        Arrays.stream(rest).allMatch(x -> are2PointsHorizontalOrVertical(point1, x));
}

就 public 接口而言,这在技术上仍然是 "one method"。如果您真的想要,您可以将助手 are2PointsHorizontalOrVertical 替换回 public 方法,但我认为这样做没有任何好处。

您可以只使用以下一种方法:

public boolean isHorizontalOrVertical(List<Point> points) {
    if (points == null || points.size() < 2) {
        throw new IllegalArgumentException("invalid number of points");
    }
    if (points.size() == 2) {
       return points.get(0).getFirstComponent() == points.get(1).getFirstComponent()
                || points.get(0).getSecondComponent() == points.get(1).getSecondComponent();
    } 
    Point start = points.get(0);
    return points.stream()
                .allMatch(p -> isHorizontalOrVertical(List.of(start, p)));
}

注意:如果您使用的不是Java版本>=9,请使用Arrays.asList instead of List.of.

其实你只能有一个方法:

public boolean isHorizontalOrVertical(Point firstPoint, Point secondPoint, Point... others) {
    // check firstPoint, secondPoint for null is ommited
    if (others == null || others.length == 0) {
        return firstPoint.getFirstComponent() == secondPoint.getFirstComponent()
                || firstPoint.getSecondComponent() == secondPoint.getSecondComponent();
    } else {
        // First, create a stream with second point + others elements
        // then match against the first point
        return Stream.of(new Point[]{secondPoint}, others).flatMap(e -> Stream.of(e))
                .allMatch(p -> isHorizontalOrVertical(firstPoint, p));
    }

}

首先我必须指出一个事实,它没有意义,至少对我来说,一种计算两个实体是水平还是垂直的方法以及那些实体是 。两点怎么可能水平或垂直?


isHorizo​​ntalOrVertical 是个坏名字

克服上述问题,您可以创建一个方法来计算两个点是水平还是垂直。

更改名称 isHorizo​​ntalOrVertical 因为它是多余的。更好的名称是 isHorizo​​ntalisVertical。该方法将 return 一个布尔值,因此如果 isHorizo​​ntal return 为假,则它是垂直的,反之亦然。 areTwoPointsHorizo​​ntal 可能是一个更好的名字,但我写这个名字时遇到了麻烦,因为它传递了错误的信息,但请随意选择你自己的名字。

所以方法,

    public boolean isHorizontal(Point first, Point second){
        boolean sameFirstComponents = firstPoint.getFirstComponent() == 
                secondPoint.getFirstComponent();
        boolean sameSecondComponents = firstPoint.getSecondComponent() == 
                secondPoint.getSecondComponent();          
        return sameFirstComponents || sameSecondComponents;
    }

最后,创建一个方法来计算列表中任意数量的点是否都在它们之间水平或垂直(假设如果点 A 与点 B 水平,则如果点 C 水平与B,与A).

重载该方法,因为它做同样的事情,唯一改变的是参数。 (注意上面简单的 isHorizo​​ntal 方法的使用)

   public boolean isHorizontal(List<Point> points){
        boolean allPointsHorizontal = true;
        for (int i=0; i<points.size(); i++) {
            
            boolean nextPointExists = i<points.size() - 1;
            if (nextPointExists) {
                Point current = points.get(i);
                Point next = points.get(i+1);
                allPointsHorizontal = allPointsHorizontal && isHorizontal(current,next);

                if (!allPointsHorizontal)
                    return false;  
            }
        }
        
        return allPointsHorizontal;
    }