从枚举到从文本文件中获取动态值

huangapple go评论78阅读模式
英文:

From enum to dynamic values from a textfile

问题

我在这里遇到了真正的困扰。我有很多包含数百个类和一些项目的Java代码。在这段代码中,我有一个职位枚举。

public enum Jobtype {

	Teacher,
	Driver,
	Nurse,
	Waiter,
	Businessman,
    Electrician
}

这个枚举在代码中的许多地方都被使用,比如Job currentjob = Job.Waiter;等等。现在我想要拥有动态的职位。通过从包含不同职位的文本文件中读取,这些职位在运行时从文本文件中添加到ArrayList中。这意味着我不能再使用枚举了,因为枚举中的职位可能会改变(也许只包含职位"engineer"和"Cook")。因此,我需要修改我的代码。我考虑创建一个名为Job的新类。

public class Job{
	
	private String Job = "";

	
	public Job(String Job) {
		
		this.Job= Job;
	}

	public String getJob() {
		return Job;
	}

	public void setJob(String Job) {
		this.Job = Job;
	}

}

然后创建一个新的ArrayList<Job> job = new ArrayList<Job>();,并根据输入添加新的职位。然而,这意味着如果我删除枚举类型,代码中将会出现许多错误。而且我无法逐个更改代码中的每个地方。有没有任何方法可以在不改变所有这些地方的情况下,仅使用数组或任何其他类型的动态代码,用户可以在运行时添加新的职位,而不是使用枚举?

例如,有一些函数:

public void someFunction(String name, Jobtype job) {
		
		if (job != Jobtype.Doctor) {
			System.out.print("%s is Not a doctor" + name);  
		} 
	}

如您所见,这些类型的函数将枚举类型"Jobtype"作为参数。如果我删除枚举,那么所有具有类似参数的函数都会出现错误。这意味着我需要在许多地方更改代码,这是低效的。我需要某种解决这个问题的方法。

提前感谢您的帮助!

英文:

I have real trouble here. I have a lot of Java code containing hundreds of classes and some projects. I have in this code a job enum.

public enum Jobtype {

	Teacher,
	Driver,
	Nurse,
	Waiter,
	Businessman,
    Electrican
}

This enum is used in tens of places in the code eg. Job currentjob = Job.Waiter; etc. Now I want to have dynamic jobs. By reading from a textfile that contain different jobs, the jobs is then added from the textfile into the ArrayList during runtime. That means I cannot have an enum anymore, because the jobs in the enum can be changed (mabey only containing only the jobs "engineer" and "Cook"). So I need to change my code. I was thinking of creating a new class called Job.

public class Job{
	
	private String Job = &quot;&quot;;

	
	public Job(String Job) {
		
		this.Job= Job;
	}

	public String getJob() {
		return Job;
	}

	public void setJob(String Job) {
		this.Job = Job;
	}

}

Then Create a new arraylist&lt;Job&gt; job = new Arraylist&lt;Job&gt;; and add new jobs based on input. However, this means if I delete the enum types I will get errors ALL over the code. And there is no way I can change every place in the code. IS there ANY way where I can just use array or any other kind of dynamic code where user can add new jobs during runtime instead of enum without having me change all these places?

For example there are functions like:

public void(String name, Jobtype job) {
		
		if (job != Jobtype.Doctor) {
			System.out.print(&quot;%s is Not a doctor&quot; + name);  
		} 
	}

As you can see these type of function have the enum type
”Jobtype” as argument. If I delete the enum then all function having similar arguments will have an error. That means I need to change the code in many places which is ineffective. I need some type of soultion for this problem.

Thanks in advance!

答案1

得分: 1

你将枚举称为 Jobs;这是一个常见的错误,应该是 Job。幸运的是,任何流行的集成开发环境(如Eclipse、IntelliJ和NetBeans)都可以轻松地重构你的整个代码库:使用“重命名”重构脚本进行重命名,工具将会一次性地为你重命名所有代码。

然后,你可以用一个类来替换这个枚举,但保留“硬编码”的角色。然而,为了确保 == 风格的相等性继续起作用,你必须确保 Job 的构造函数保持为私有。

public class Job {
    private final String job;

    private static final Map<String, Job> cache = new HashMap<>();

    private Job(String job) {
        this.job = job;
    }

    public static Job of(String job) {
        return cache.computeIfAbsent(job, j -> new Job(j));
    }

    public static final Job Doctor = of("Doctor");
    // 为所有现有枚举值重复此操作。
}

在这一点上,你仍然可以编写 Job.Doctor,甚至是 Job.Doctor == Job.of("Doctor"),一切都会继续正常工作。你可以忽略本答案开头描述的重构,但那样你就有了一个命名错误的类型。

注:这个类最终会开始泄漏内存,但只有在你发明了成千上万的工作标题时才会出现这种情况。请注意,如果这在公共网站上运行,有人可能会编写脚本,但除了那种滥用,这不会成为问题。如果这是一个问题,更复杂的重构可能是你唯一的解决方案。

英文:

You called your enum Jobs; that's a common mistake, it should have been Job. Fortunately, any popular IDE (Eclipse, intellij, and netbeans can all do this) can trivially refactor your entire codebase here: Rename it using the 'rename' refactor script and the tool will rename all the code for you, in one go.

Then, you can replace the enum with a class, but keep the 'hardcoded' roles. However, to ensure that == style equality continues to function, you must ensure that the constructor of Job remain private.

public class Job {
    private final String job;

    private static final Map&lt;String, Job&gt; cache = new HashMap&lt;&gt;();

    private Job(String job) {
        this.job = job;
    }

    public static Job of(String job) {
        return cache.computeIfAbsent(job, j -&gt; new Job(j));
    }

    public static final Job Doctor = of(&quot;Doctor&quot;);
    // repeat for all your existing enum values.
}

At that point, you can still write Job.Doctor, and even Job.Doctor == Job.of(&quot;Doctor&quot;) and all will continue to work. You can omit the refactor described at the top of this answer, but then you have a misnamed type.

NB: This class would, eventually, start leaking memory but only if you invent hundreds of thousands of job titles. Be aware that if this is running on a public site someone could be a real clown and write a script, but short of that sort of abuse, it won't be an issue. if it is an issue, a more complicated refactor is probably your only solution.

huangapple
  • 本文由 发表于 2020年10月18日 03:09:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/64406315.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定