这被认为是不好的做法吗?本质上,基于枚举我想在接口中调用特定方法.每个枚举都有自己的接口实现(WalkImpl,RunImpl,JogIMpl等),所有这些都基于ActivityService接口.我只是想知道这是将服务"注入"Enum的正确方法.我这样做是因为我无法自动提供服务.谢谢
@Component
public class HelloWorldImpl implements HelloWorld {
private enum MyEnum{
WALK {
@Override
public void execute() {
System.out.println("I am walking");
activityService.doSomethingWithMe(this.name());
}
},
RUN{
@Override
public void execute() {
System.out.println("I am running");
}
},JOG{
@Override
public void execute() {
System.out.println("I am jogging!");
}
}, SKIP{
@Override
public void execute() {
System.out.println("I am skipping!");
}
};
public abstract void execute();
private static ActivityService activityService;
public void setActivityService(ActivityService activityService) {
this.activityService = activityService;
}
}
@Autowired
ActivityService activityService;
@Override
public void executeMe(){
MyEnum myEnum = MyEnum.WALK;
myEnum.setActivityService(activityService);
myEnum.execute();
}
}
Run Code Online (Sandbox Code Playgroud)
不要使用这样的枚举.当我有更多的时间我将解释,但大多数程序员期望甚至Java语言有点期望枚举是幂等的和不可改变的.
枚举中的所有成员变量都应该是final,枚举不应该产生副作用.这是因为枚举是函数式编程风格调度的一种形式(尽管很糟糕).这应该被视为符号而不是对象(即使它们是单例对象).
除非您遵循上面的功能规则,否则不要使用枚举来解决单例模式.以下是我可能会对您的代码进行修改:
@Component
public class HelloWorldImpl implements HelloWorld {
private enum MyEnum{
//Notice the final here
private final String message;
WALK ("I am walking"),
RUN("I am running"),
JOG("I am jogging!"),
SKIP("I am skipping!");
public MyEnum(String message) { this.message = message; }
public String getMessage() { return this.message; }
}
@Autowired
ActivityService activityService;
@Override
public void executeMe() {
MyEnum myEnum = MyEnum.WALK;
_executeMe(myEnum);
}
void _executeMe(MyEnum m) {
//switch or if on the enums you want to
//do stuff on with the activity service.
System.out.println(m.getMessage());
if (m == MyEnum.WALK)
activityService.doSomethingWithMe(m.name());
}
}
Run Code Online (Sandbox Code Playgroud)
枚举最适合在代码中必须区分的事物——业务逻辑。如果您将它们用于数据(如您的示例),那么对我来说没有任何意义。
另外,通过数据与代码,我并不是在谈论简单地迭代它们,您实际上必须使用不同的枚举来拥有显着不同的代码,否则它们只是一个(坏的)数据初始化设备。
该类型数据的更好初始化可能是:
String[] init=new String[] {"WALK", "I am walking", "SKIP", "I am skipping", ...}
Map lookup=new HashMap();
for(int i=0;i+=2;i<init.length)
{
lookup.put(init[i],init[i+1])
}
Run Code Online (Sandbox Code Playgroud)
没有冗余,更简单,当该列表变得更加复杂时,将其从代码中取出到文本、属性、xml 或您喜欢的任何类型的数据中都很简单。
您甚至可以将代码与这些关联起来,如果这就是您想要的,通过将“Lookup”和整个初始化包装到一个对象中(一个好主意)我会制作如下所示的东西:
public class Motivate()
{
private static Map<String, Motivate> motivations;
private String action;
private String description;
private Motivate(String action, String description)
{
this.action=action;
this.description=description;
}
public void init()
{
if(motivations == null)
{
build motivations using all the stuff in the first example
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您想要附加不同的代码(假设您的示例很简单,并且每个“模式”需要不同的代码),请添加一个包含“Runnable”等接口的成员,并在构建它们时将其传递到构造函数中。
那么您的代码永远不应该引用“RUN”或“WALK”,它只是绑定到例如用户击键或其他一些数据的数据。
| 归档时间: |
|
| 查看次数: |
4398 次 |
| 最近记录: |