简体   繁体   English

Java,带有构造函数的枚举

[英]Java, enum with constructor

I'm refactoring some legacy system written in Java, and I came across a problem with an enum constructor. 我正在重构一些用Java编写的遗留系统,但遇到了枚举构造函数的问题。

I have an enum class like this (just an example): 我有一个这样的枚举类(仅作为示例):

public enum Signal{
   ON(new InButton()),
   OFF(new OutButton())

   private final Button button;

   Signal(Button button) {
       this.button = button;
   }
}

InButton and OutButton extends the Button interface. InButton和OutButton扩展了Button接口。

The enum values are accessed for the first time using Signal.Values() method. 枚举值是使用Signal.Values()方法首次访问的。 (Also, in one of the Button method, I have a code that uses the enum, such as activateButton(Signal.ON)) (此外,在Button方法之一中,我有一个使用枚举的代码,例如activateButton(Signal.ON)。)

While refactoring the code, I wanted to create a new constructor for Button that express it dependency, such as Button(String input). 重构代码时,我想为Button创建一个新的构造函数来表达它的依赖性,例如Button(String input)。

The problem is that I don't know how to pass the new parameters to the enum button field. 问题是我不知道如何将新参数传递给枚举按钮字段。 What is the right way to deal with this situation? 处理这种情况的正确方法是什么? Is this enum should be used at all? 完全应该使用这个枚举吗?


Clarification after Jean Logeart question: InButton and OutButton also have a constructor with a String arguments. Jean Logeart问题后的澄清: InButtonOutButton也具有带有String参数的构造函数。 I'd rather avoid it to be initialize to null because than it could create other problems. 我宁愿避免将其初始化为null,因为它可能会引起其他问题。

Basically this question is how to mimic a=f(x) using java syntax. 基本上,这个问题是如何使用Java语法模拟a = f(x)。 Most of the time I can do: 大多数时候我可以做:

  1. y = new x(); y = new x(); a = new f(y); a =新的f(y);
  2. a = new f(new x()); a = new f(new x());
  3. a = new f(null); a =新的f(null); a.getF().setX(new x()); a.getF()。setX(new x());

In this case I can't do it. 在这种情况下,我做不到。

I suggest not having the enums know about the buttons at all. 我建议完全不要让枚举数了解按钮。 Just have them enumerate the possible signals, and put the job of mapping signal->button somewhere else: 只是让它们枚举可能的信号,然后将映射信号->按钮的工作放在其他位置:

Function<Signal, Button> signalToButton = ...

That will also make it easier to inject different buttons for testing; 这也将使注入不同的按钮进行测试变得更加容易。 for instance, you can inject a mocked Button that confirms that it was our wasn't pressed. 例如,您可以注入模拟的Button,以确认没有按下我们的按钮。

As far as using that mapping in your code: you can "install" a mapping to some static field, or, better yet, provide it as a constructor argument to any code that needs it. 至于在代码中使用该映射:您可以“安装”到某个静态字段的映射,或者更好的是,将它作为需要它的任何代码的构造函数参数提供。 Dependency injection is very helpful for the latter option, but that may be a bigger change. 依赖注入对后一种选择非常有帮助,但这可能是一个更大的变化。

Two main options. 两个主要选项。

First one, InButton and OutButton also have a constructor with a String argument in which case you need to provide a String when instanciating: 第一个, InButtonOutButton也具有带有String参数的构造函数,在这种情况下,您需要在实例化时提供String

public class InButton extends Button {
    public InButton(String s) {
        super(s);
    }
}
// ...
public enum Signal{
    ON(new InButton("in"))
    // ...
}

Second option, InButton and OutButton are instanciated with a specific String in which case no refactoring is necessary in the enum : 第二个选项InButtonOutButton用特定的String实例化,在这种情况下, enum不需要重构:

public class InButton extends Button {
    public InButton() {
        super("in");   // default value
    }
}
// ...
public enum Signal{
    ON(new InButton())   // same as before
    // ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM