Java 我的生成器实现是否违反了可变性

Java 我的生成器实现是否违反了可变性,java,optimization,mutability,Java,Optimization,Mutability,我想知道我对QuestionBuilder的实现是否违反了可变性 public class Question<T extends Serializable> implements Serializable { private QuestionHolder<T> questionHolder; private Question(QuestionHolder<T> questionHolder) { this.questionH

我想知道我对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;
        }

    }

}
公共类问题实现可序列化{
私人提问者;
私人问题(问题持有人问题持有人){
this.questionHolder=questionHolder;
}
公共字符串getId(){
返回问题持有者id;
}
public int getOrder(){
退回订单;
}
公共问题类型getType(){
return.type;
}
公共布尔值isImmediate(){
立即返回问题持有人;
}
公共布尔值是强制性的(){
返回问题持有人。必填项;
}
公共列表getSelectedValues(){
返回问题持有者。选择的值;
}
公共列表getPossibleValues(){
返回问题持有者。可能值;
}
私有静态最终类问题持有者{
私有字符串id;
私有整数阶=0;
私人问题类型;
私有布尔立即数;
私有布尔强制;
私有列表选择值;
私有列表可能值;
}
公共静态最终类QuestionBuilder实现生成器{
私人提问者;
公共问题生成器(字符串id){
提问者=新的提问者();
questionHolder.id=id;
}
公共问题生成器withOrder(整数顺序){
问题持有者。顺序=顺序;
归还这个;
}
公共提问生成器withType(QuestionType QuestionType){
questionHolder.type=questionType;
归还这个;
}
公共问题生成器withImmediate(布尔立即){
questionHolder.immediate=立即;
归还这个;
}
带必填项的公共问题生成器(布尔必填项){
questionHolder.mandatory=强制;
归还这个;
}
带有选定值的公共问题生成器(列出选定值){
questionHolder.selectedValues=selectedValues;
归还这个;
}
具有可能值的公共问题生成器(列出可能值){
questionHolder.possibleValues=possibleValues;
归还这个;
}
公共问题构建(){
问题=新问题(问题持有人);
提问者=null;
返回问题;
}
}
}

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

据我所知,您每次调用构建器时都会对问题负责人进行变异。 我要做的是:

1) 将问题持有者内的所有属性设置为私有,并且根本不创建任何设置器

2) 将每个属性存储在生成器实例中,并在生成器的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);
}
公共问题构建(){
//完成所有需要的验证
问题持有者=新的问题持有者(id、顺序、类型、中间、必填、选定值、可能值);
返回新问题(问题持有人);
}

使用这些方法,您将对构建器进行变异,但对于构建器模式来说,这没关系。显然,每次创建问题时都需要创建一个新的生成器实例。如果您想反复使用同一个构建器,您可能需要在其中存储某种结构(例如,由Id标识的映射)。

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

一个线程调用build()并返回指向提问者的问题是可能的。即使build()将holder设置为null,另一个线程也可能看不到该null,而是看到该字段的旧值。如果另一个线程调用了您的任何setter,它可能会变异问题类已经访问的Holder


在单线程应用程序中,您会很好。

您看到了什么可变性问题?我看不到。我只是问,因为我不确定。那么,如果你认为自己没有“可变性问题”,为什么你会对“可变性问题”产生怀疑呢?。。。我不明白你想问什么。至少要弄清楚你要问的“易变性问题”,基本上我有问题,因为我不确定类是否设计得很好。通常我们不会在不同的线程中使用相同的生成器。