【问题标题】:Java8 using enum values in interface's default methodsJava 8 在接口默认方法中使用枚举值
【发布时间】:2016-10-26 09:15:09
【问题描述】:

我正在探索 java 8 中引入的静态和默认方法的可能性。

我有一个接口,它有 2 个构建命令的默认方法,我通过 ssh 在服务器上运行以远程执行一些简单的任务。移动鼠标需要 2 个参数:鼠标的 x 和 y 位置。

public interface Robot {

    default String moveMouse(int x, int y) {
        return constructCmd("java -jar move_mouse.jar " + x + " " + y);
    }

    default String clickLeft() {
        return  constructCmd("java -jar click_left.jar");
    }

    static String constructCmd(String cmd) {
        return "export DISPLAY=:1.0\n" +
                "cd Desktop\n" +
                cmd;
    }
} 

我有多个带有预设值的枚举,我可以有效地将所有枚举组合成一个而不使用任何接口,但是该枚举将包含数百或数千个值,我想保持它有条理,所以我已经将 evertying 拆分为多个枚举。

我希望所有枚举共享相同的方法,所以我想我会在接口中提供默认方法。

public enum Field implements Robot {

    AGE_FIELD(778, 232),

    NAME_FIELD(662, 280);

    public int x;
    public int y;

    Field(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

所以我可以通过以下方式获取字符串命令:

Field.AGE_FIELD.clickLeft();
Field.AGE_FIELD.moveMouse(Field.AGE_FIELD.x, Field.AGE_FIELD.y);

但是 moveMouse 对我来说看起来真的很糟糕,我认为默认情况下应该可以使用枚举的值。

谁有解决这个问题的好办法?

【问题讨论】:

  • 这似乎是一个概念问题。你想要的是一个带有void moveMouse()int getMouseTargetX()int getMouseTargetY() 方法的接口。您当前的设计需要特定的 x 和 y 坐标。我的建议假设对象具有一些属性,定义 x 和 y 坐标。我的建议更像是对现有系统的扩展,而不是替代。您的接口将用于组件实际移动鼠标,而我的接口将由组件使用,组件调用实际移动鼠标的组件。

标签: java enums interface java-8


【解决方案1】:

问题在于您的架构。一方面,您有一个实际执行鼠标移动的层(由您的Robot 接口表示)。现在,您需要一个层来产生鼠标移动并将其发送到Robot 以执行此鼠标移动。让我们调用定义该层的接口MouseTarget(非常适合您的示例):

public interface MouseTarget {
    int getTargetX();
    int getTargetY();

    default void moveMouseHere(Robot robot) {
        robot.moveMouse(this.getTargetX(), this.getTargetY());
    }
}

这个界面代表一个鼠标移动到一个目标。如您所见,moveMouseHere(Robot robot) 方法需要 Robot 将移动发送到(实际工作)。现在,剩下的就是调整您的 Fields 枚举:

public enum Fields implements MouseTarget {

    AGE_FIELD(778, 232), NAME_FIELD(662, 280);

    public int targetX;
    public int targetY;

    Fields(int targetX, int targetY) {
        this.targetX = targetX;
        this.targetY = targetY;
    }

    @Override
    public int getTargetX() {
        return targetX;
    }

    @Override
    public int getTargetY() {
        return targetY;
    }
}

【讨论】:

  • 修饰符 'public' 对于接口方法来说是多余的
【解决方案2】:

由于您可能希望有多个Robot 的实现,我显然不会像您那样继续,我宁愿为您的枚举方法提供一个Robot 实例,而不是实现接口Robot,它然后会更灵活,更容易测试。

枚举Field

public enum Field {

    ...

    public String moveMouse(Robot robot) {
        return robot.moveMouse(x, y);
    }

    public String clickLeft(Robot robot) {
        return robot.clickLeft();
    }
}

即使不是严格意义上的Strategy pattern,它在全球范围内都是相同的方法。

【讨论】:

    猜你喜欢
    • 2011-10-27
    • 1970-01-01
    • 2021-08-24
    • 2018-01-28
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    • 2020-03-03
    • 2021-08-23
    相关资源
    最近更新 更多