6

所以,举个例子,假设我们有一个abstract class被调用的Question,该问题包含很多字符串,一个用于问题本身,一个用于答案,两个响应发布给用户,如果他的问题是对的/错的。

public abstract class Question {

    private final String question;
    private final String answer;
    private final String answerCorrect;
    private final String answerWrong;

}

我的问题基本上是,初始化所有字符串的常用方法是什么?到目前为止,我已经编写了 2 个关于如何做到这一点的版本,它们各有优缺点,我想知道是否有某种“最佳编码实践”。


版本 A
初始化构造函数中的所有内容。

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;

    }
}

这看起来很方便,我唯一遇到的问题是用户不确定字符串的顺序。

public class ExampleClass extends Question {

    public ExampleClass() {
        super("I think, that's the answer", "and that's the question", "answer wrong?", "answer right?");
    }

}

版本 B
不要立即初始化并等待用户执行。

public abstract class Question {

    //...

    public Question() {

        this.question = "";
        this.answer = "";
        this.answerCorrect = "";
        this.answerWrong = "";

    }

    public void setQuestion(String question) {
        this.question = question;
    }

    //...
}

这使得初始化变量变得更容易,但字符串不能再存在final了,并且不能保证用户会初始化所有变量。


我也想过让子类实现在构造函数中调用的抽象方法Question来初始化所有字符串并保留它们final,但那个版本对我来说似乎有点太奇怪了。

还有其他/更好的方法吗?我应该更喜欢哪个版本?
预先感谢您的支持。

4

3 回答 3

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'

注意:我意识到最初的问题是关于抽象类的。我使用了一个具体的类,所以我可以给出一个工作示例,尽管该解决方案可以适用于抽象类。

于 2013-10-15T16:21:11.597 回答
1

与其将属性(例如question)视为变量,不如考虑对它们的值的限制,这些限制必须遵守才能使类正确运行。它们可以为空吗?它们可以是空的吗?现在设计您的方法构造函数,这样就不可能打破这些限制。您可能会发现,您可以这样做的唯一方法是在构造函数(您的版本 A)中设置初始值。您可能必须在构造函数和 setter 方法中添加前置条件检查,如果传递给它们的值会导致限制被破坏,它们会检查给定抛出适当异常 (NullPointerException或) 的值。IllegalArgumentException

另外,请考虑在构造对象之后更改属性的值是否真的有意义。如果不是,那么该属性不应该是一个设置器,使您的版本 B 不可能。

于 2013-10-15T20:28:34.397 回答
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;

}
于 2013-10-15T16:01:31.810 回答