摆脱枚举中的代码重复

时间:2014-05-07 07:08:24

标签: java enums code-duplication

我有一个接口,我希望枚举实现它,但有些方法是相同的,它会导致代码重复。我会使用抽象类而不是接口,但java不允许枚举扩展任何东西。有没有解决的办法?我提供了一些代码来帮助理解问题。

public interface CommandI {
  boolean isCommand(String command);
  void execute(Drawer drawer, Creature creature);
  String getDescription();
}



public enum Command2 implements CommandI {
  FORWARD{
    private String description = "qwersadd";
    private String[] aliases = {"fd", "forward"};
    @Override
    public boolean isCommand(String command) {
        for (String s: aliases){
        if (s.equals(command)){
          return true;
        }
      }
      return false;
    }
    @Override
    public void execute(Drawer drawer, Creature creature) {
      throw new UnsupportedOperationException("Not supported yet.");
    }
    @Override
    public String getDescription() {
      return description;
    }
  },
  PENUP{
    private String description = "vcvzxcvz";
    private String[] aliases = {"pu", "penup"};
    @Override
    public boolean isCommand(String command) {
        for (String s: aliases){
        if (s.equals(command)){
          return true;
        }
      }
      return false;
    }
    @Override
    public void execute(Drawer drawer, Creature creature) {
      throw new UnsupportedOperationException("Not supported yet.");
    }
    @Override
    public String getDescription() {
      return description;
    }
  }

}

如您所见,只有执行方法会有所不同。

3 个答案:

答案 0 :(得分:5)

我不确定你是否真的明白如何使用枚举。以下是您应该实现Command2的方式:

public enum Command2 implements CommandI {

    FORWARD("qwersadd", new String[] { "fd", "forward" }),
    PENUP("vcvzxcvz", new String[] { "pu", "penup" });

    private final String description;
    private final String[] aliases;

    private Command2(String description, String[] aliases) {
        this.description = description;
        this.aliases = aliases;
    }

    @Override
    public boolean isCommand(String command) {
        for (String s : aliases) {
            if (s.equals(command)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void execute(Drawer drawer, Creature creature) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public String getDescription() {
        return description;
    }

}

您希望实现execute FORWARD正文的时间,只需(覆盖)覆盖它,如下所示:

FORWARD("qwersadd", new String[] { "fd", "forward" }) {
    @Override
    public void execute(Drawer drawer, Creature creature) {
        // specific execute body for FORWARD
    }
}

答案 1 :(得分:3)

您可以在枚举本身中定义抽象方法,并使用模板方法模式:

public enum Command2 implements CommandI {
    FORWARD {
        private String description = "qwersadd";
        private String[] aliases = {"fd", "forward"};

        @Override
        protected String[] getAliases() {
            return aliases;
        }

        @Override
        public String getDescription() {
            return description;
        }
    },
    PENUP {
        private String description = "vcvzxcvz";
        private String[] aliases = {"pu", "penup"};

        @Override
        protected String[] getAliases() {
            return aliases;
        }

        @Override
        public String getDescription() {
            return description;
        }
    };

    protected abstract String[] getAliases();

    @Override
    public boolean isCommand(String command) {
        for (String s : getAliases()) {
            if (s.equals(command)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void execute(Drawer drawer, Creature creature) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

但在这种特殊情况下,由于所有方法都以相同的方式实现,并且所有枚举具有相同的状态,the answer from @sp00m是解决问题的更好方法。

答案 2 :(得分:0)

这个回复主要是学术性的,但确实回答了这个问题。如果它没用,我道歉。

如果你真的想解决这个问题,你可以做一些回旋。您可以创建一个扩展enum的抽象类,然后将您的实现放在那里。然后,您可以创建另一个扩展AbstractEnum类并实现ICommand的类。这可能是最犹豫的做事方式。

但是,如果你只想简化这个,你可以添加一个Runnable并通过构造函数传递它。