所以,举个例子,假设我们有一个名为abstract class
的{{1}},该问题包含很多字符串,一个用于问题本身,一个用于答案,两个响应发布到用户,如果他的问题是对/错。
Question
我的问题基本上是,初始化所有字符串的常用方法是什么?到目前为止,我已经编写了2个关于如何做的版本,它们有它们的上下限,我想知道,如果有这种“最佳编码实践”。
版本A
初始化构造函数中的所有内容。
public abstract class Question {
private final String question;
private final String answer;
private final String answerCorrect;
private final String answerWrong;
}
这看起来非常方便,我遇到的唯一问题是用户不确定字符串必须按顺序排列。
public abstract class Question {
//...
public Question(String question, String answer, String answerCorrect, String answerWrong) {
this.question = question;
this.answer = answer;
this.answerCorrect = answerCorrect;
this.answerWrong = answerWrong;
}
}
版本B
不要立即初始化并等待用户这样做。
public class ExampleClass extends Question {
public ExampleClass() {
super("I think, that's the answer", "and that's the question", "answer wrong?", "answer right?");
}
}
这样可以更容易地初始化变量,但字符串不能再为public abstract class Question {
//...
public Question() {
this.question = "";
this.answer = "";
this.answerCorrect = "";
this.answerWrong = "";
}
public void setQuestion(String question) {
this.question = question;
}
//...
}
,并且无法保证用户将初始化所有变量。
我还考虑让子类实现在final
的构造函数中调用的抽象方法来初始化所有字符串并保留它们Question
,但是那个版本看起来有点像对我来说太奇怪了。
还有其他/更好的方法吗?我应该选择什么版本?
在此先感谢您的支持。
答案 0 :(得分:1)
版本A是要走的路。不过,你是对的,如果你不告诉你的用户(我假设的其他开发者)哪个参数是哪个,他们就无法知道在哪里输入什么。
这是Javadoc派上用场的地方。
以下是一个例子:
/**
* Create a new instance of Question given the following parameters:
*
* @param question This is the question
* @param answer This is the answer
* @param answerCorrect Whenever someone guesses correct, print this
* @param answerWrong Whenever someone guesses wrong, print this
*/
public Question(String question, String answer, String answerCorrect, String answerWrong) {
this.question = question;
this.answer = answer;
this.answerCorrect = answerCorrect;
this.answerWrong = answerWrong;
}
答案 1 :(得分:1)
这可能有点矫枉过正,但我相信你可以在这里使用建设者......
public class Question
{
private final String question;
private final String answer;
private final String answerCorrect;
private final String answerWrong;
Question(QuestionBuilder builder) {
this.question = builder.question;
this.answer = builder.answer;
this.answerCorrect = builder.answerCorrect;
this.answerWrong = builder.answerWrong;
}
// public getters omitted to shorten answer
@Override
public String toString(){
return String.format("question: '%s', answer: '%s', answerCorrect: '%s', answerWrong: '%s'", question, answer, answerCorrect, answerWrong);
}
public static void main(String[] args) {
QuestionBuilder qb = new QuestionBuilder();
qb = qb.question("This is the question").answer("This is the answer").answerCorrect("Correct answer").answerWrong("Wrong Answer");
Question question = new Question(qb);
System.out.println(question);
}
public static class QuestionBuilder{
private String question;
private String answer;
private String answerCorrect;
private String answerWrong;
public QuestionBuilder question(String question) {
this.question = question;
return this;
}
public QuestionBuilder answer(String answer) {
this.answer = answer;
return this;
}
public QuestionBuilder answerCorrect(String answerCorrect) {
this.answerCorrect = answerCorrect;
return this;
}
public QuestionBuilder answerWrong(String answerWrong) {
this.answerWrong = answerWrong;
return this;
}
}
}
提供输出
question: 'This is the question', answer: 'This is the answer', answerCorrect: 'Correct answer', answerWrong: 'Wrong Answer'
注意:我意识到最初的问题是参考抽象类。我使用了一个具体的类,所以我可以提供一个工作示例,尽管该解决方案可以适用于抽象类。
答案 2 :(得分:1)
不要将属性(例如question
)视为变量,而应考虑其值必须遵守的限制,以使类行为正确。他们可以为空吗?他们可以是空的吗?现在设计你的方法和构造函数,这样就不可能破坏这些限制。您可能会发现 only 方式可以在构造函数(您的版本A)中设置初始值。您可能必须将前置条件检查添加到构造函数和setter方法中,如果传递给它们的值将导致限制,则会检查抛出适当异常(NullPointerException
或IllegalArgumentException
)的值被打破了。
另外,考虑构造对象后是否确实更改属性的值是有意义的。如果没有,那么该属性不应该是一个setter,使你的版本B不可能。