在抽象类中保存数据的最佳实践

时间:2013-10-15 15:54:18

标签: java initialization abstract-class

所以,举个例子,假设我们有一个名为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,但是那个版本看起来有点像对我来说太奇怪了。

还有其他/更好的方法吗?我应该选择什么版本?
在此先感谢您的支持。

3 个答案:

答案 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方法中,如果传递给它们的值将导致限制,则会检查抛出适当异常(NullPointerExceptionIllegalArgumentException)的值被打破了。

另外,考虑构造对象后是否确实更改属性的值是有意义的。如果没有,那么该属性不应该是一个setter,使你的版本B不可能。