使用setter将服务注入到Enum ... Bad Practice? [英] using setter to inject service into Enum...Bad Practice?

查看:386
本文介绍了使用setter将服务注入到Enum ... Bad Practice?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是否被认为是坏习惯?本质上,根据枚举,我想在界面中调用一个特定的方法。每个枚举都将具有自己的接口实现(WalkImpl,RunImpl,JogIMpl等等),所有这些都基于ActivityService接口。我只想知道这是将服务注入到枚举中的正确方法。我这样做是因为我无法自动连接服务。感谢

  @Component 
public class HelloWorldImpl实现HelloWorld {

private enum MyEnum {

WALK {
@Override
public void execute(){
System.out.println(I'm walking);
activityService.doSomethingWithMe(this.name());
}
},
RUN {
@Override
public void execute(){
System.out.println(I'm running);
}
},JOG {
@Override
public void execute(){
System.out.println(I'm jogging!);
}
},SKIP {
@Override
public void execute(){
System.out.println(I'm skip!!);
}
};

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();

}
}


解决方案

枚举最适用于必须在代码 - 业务逻辑中区分的事物。如果您正在使用它们作为数据(如您的示例),那对我来说没有任何意义。



另外,通过数据vs代码我不是在简单地迭代它们,实际上必须使用不同的枚举显着不同的代码,否则它们只是一个坏)数据初始化设备。



更好地初始化该类型的数据可能是:

  String [] init = new String [] {WALK,我正在走,SKIP,我正在跳过,...} 
Map lookup = new HashMap(); (int i = 0; i + = 2; i {
lookup.put(init [i],init [i + 1])$ ​​b $ b }

没有冗余,更简单,当列表变得更加复杂时,将它放在代码到文本,属性,xml或任何你喜欢的数据风格。



你甚至可以将代码与这些相关联,如果这是你以后通过包装查找这个整个初始化成一个对象(一个好主意)我会做一些这样的东西:

  public class Activivate ()
{

private static Map< String,Motivate>动机;
private String action;
private String description;

private Motivate(String action,String description)
{
this.action = action;
this.description = description;
}
public void init()
{
if(motivations == null)
{
使用第一个例子中的所有内容构建动机
}
}
}

如果你想要不同的代码假设你的例子是微不足道的,每个模式都需要不同的代码),添加一个包含Runnable的界面的成员,并在构建器时将其传递给构造函数。



然后,您的代码不应该引用RUN或WALK,它只是绑定的数据,例如用户按键或其他数据。


Is this considered bad practice? Essentially, based on the enum I want to call a specific method in an interface. Each enum will have its own interface implementation (WalkImpl,RunImpl,JogIMpl, etc....) all based off of the ActivityService interface. I just wanted to know is this the right way to "inject" a service into an Enum. I am doing it this way since I can't autowire the service. Thanks

@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();

  }
}

解决方案

Enums are best used for things that MUST be differentiated in code--business logic. If you are using them for data (as your example), it doesn't make any sense to me.

Also, by data vs code I'm not talking about simply iterating over them, you actually have to have significantly different code USING different enums, otherwise they are just a (bad) data initialization device.

A better initialization of that type of data might be:

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])
}

No redundancy, much simpler, and when that list becomes more complicated it's trivial to take it outside of the code to a text, properties, xml or whatever flavor of data you prefer.

You can even associate code with these if that is what you are after by wrapping "Lookup" and this entire initialization into an object (A good idea) I'd make something that looked like this:

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
        }
    }
}

If you want different code attached (assuming your examples were just trivial and each "Mode" needed different code), add a member that holds an interface like "Runnable" and pass that into the constructor when you build them.

Then your code should never refer to "RUN" or "WALK", it is just data that is bound, for instance, to a users keystroke or some other data.

这篇关于使用setter将服务注入到Enum ... Bad Practice?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆