Java 我的生成器实现是否违反了可变性
我想知道我对QuestionBuilder的实现是否违反了可变性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
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
在单线程应用程序中,您会很好。您看到了什么可变性问题?我看不到。我只是问,因为我不确定。那么,如果你认为自己没有“可变性问题”,为什么你会对“可变性问题”产生怀疑呢?。。。我不明白你想问什么。至少要弄清楚你要问的“易变性问题”,基本上我有问题,因为我不确定类是否设计得很好。通常我们不会在不同的线程中使用相同的生成器。