0

我想知道我对 QuestionBuilder 的实现是否违反了可变性。

public class Question<T extends Serializable> implements Serializable {

    private QuestionHolder<T> questionHolder;

    private Question(QuestionHolder<T> questionHolder) {
        this.questionHolder = questionHolder;
    }

    public String getId() {
        return questionHolder.id;
    }

    public int getOrder() {
        return questionHolder.order;
    }

    public QuestionType getType() {
        return questionHolder.type;
    }

    public boolean isImmediate() {
        return questionHolder.immediate;
    }

    public boolean isMandatory() {
        return questionHolder.mandatory;
    }

    public List<T> getSelectedValues() {
        return questionHolder.selectedValues;
    }

    public List<T> getPossibleValues() {
        return questionHolder.possibleValues;
    }

    private static final class QuestionHolder<T extends Serializable> {

        private String id;

        private int order = 0;

        private QuestionType type;

        private boolean immediate;

        private boolean mandatory;

        private List<T> selectedValues;

        private List<T> possibleValues;
    }

    public static final class QuestionBuilder<T extends Serializable> implements Builder<Question<T>> {

        private QuestionHolder<T> questionHolder;

        public QuestionBuilder(String id) {
            questionHolder = new QuestionHolder<>();
            questionHolder.id = id;
        }

        public QuestionBuilder withOrder(int order) {
            questionHolder.order = order;
            return this;
        }

        public QuestionBuilder withType(QuestionType questionType) {
            questionHolder.type = questionType;
            return this;
        }

        public QuestionBuilder withImmediate(boolean immediate) {
            questionHolder.immediate = immediate;
            return this;
        }

        public QuestionBuilder withMandatory(boolean mandatory) {
            questionHolder.mandatory = mandatory;
            return this;
        }

        public QuestionBuilder withSelectedValues(List<T> selectedValues) {
            questionHolder.selectedValues = selectedValues;
            return this;
        }

        public QuestionBuilder withPossibleValues(List<T> possibleValues) {
            questionHolder.possibleValues = possibleValues;
            return this;
        }

        public Question<T> build() {
            Question<T> question = new Question<>(questionHolder);
            questionHolder = null;
            return question;
        }

    }

}

或者我应该调整什么来解决可变性问题。有什么建议么?

4

2 回答 2

0

如果您担心线程安全,那么您这里的代码不一定是线程安全的。

有可能一个线程调用 build() 并返回一个指向 QuestionHolder 的 Question。即使 build() 将持有者设置为 null,另一个线程可能看不到该 null,而是看到该字段的旧值。如果那个其他线程调用了你的任何设置器,它可能会改变 Question 类已经访问过的 Holder。

在单线程应用程序中,你会没事的。

于 2015-10-29T15:05:26.363 回答
0

据我所知,您在每次构建器调用时都会改变 QuestionHolder 。我会做的是:

1) 将 QuestionHolder 中的所有属性设为私有,并且根本不创建任何设置器。

2)将每个属性存储在builder实例中,并在builder的build方法中创建一个新的QuestionHolder实例。

例如:

public Question<T> build() {
    // DO ALL THE VALIDATIONS NEEDED
    QuestionHolder holder = new QuestionHolder(id, order, type, inmediate, mandatory, selectedValues, possibleValues);
    return new Question<>(questionHolder);
}

使用这些方法,您将改变 Builder,但这对于 Builder 模式来说是可以的。显然,每次要创建问题时,您都需要创建一个新的 Builder 实例。如果您想一遍又一遍地使用同一个 Builder,您可能需要在其中存储某种结构(例如,由 Id 标识的 Map)。

于 2015-10-29T15:02:40.847 回答