源代码

public static Builder builder() {
		return new Builder();
	}


	public static class Builder {

		private final SearchRequest searchRequest = new SearchRequest();

		public Builder query(String query) {
			Assert.notNull(query, "Query can not be null.");
			this.searchRequest.query = query;
			return this;
		}

		public Builder topK(int topK) {
			Assert.isTrue(topK >= 0, "TopK should be positive.");
			this.searchRequest.topK = topK;
			return this;
		}

		public Builder similarityThreshold(double threshold) {
			Assert.isTrue(threshold >= 0 && threshold <= 1, "Similarity threshold must be in [0,1] range.");
			this.searchRequest.similarityThreshold = threshold;
			return this;
		}

		public Builder similarityThresholdAll() {
			this.searchRequest.similarityThreshold = 0.0;
			return this;
		}

		public Builder filterExpression(@Nullable Filter.Expression expression) {
			this.searchRequest.filterExpression = expression;
			return this;
		}

		public Builder filterExpression(@Nullable String textExpression) {
			this.searchRequest.filterExpression = (textExpression != null)
					? new FilterExpressionTextParser().parse(textExpression) : null;
			return this;
		}

		public SearchRequest build() {
			return this.searchRequest;
		}
	}

Q: 为什么 private final SearchRequest searchRequest = new SearchRequest(); 要加 private 和 final?

private 表示这个字段只能在 Builder 类内部访问,外部无法直接操作。这是封装性的体现:

// 外部代码无法这样访问(编译错误)
SearchRequest.Builder builder = SearchRequest.builder();
builder.searchRequest.query = "test"; // ❌ 编译错误,searchRequest是private的

final 表示这个引用一旦赋值就不能再指向其他对象:

public static class Builder {
    private final SearchRequest searchRequest = new SearchRequest();
    
    // 不能这样做(编译错误)
    public void someMethod() {
        this.searchRequest = new SearchRequest(); // ❌ 编译错误,final不能重新赋值
    }
}
为什么要这样子设计?
  1. 安全性:防止外部代码意外修改构建过程中的对象状态

  2. 一致性:确保整个构建过程操作的是同一个 SearchRequest 实例

  3. 线程安全:在多线程环境下更安全(虽然不是完全线程安

Q: 为什么要用 this.searchRequest.query = query 而不是直接 searchRequest.query = query

  1. 性能更好:避免在 build() 时创建新对象和复制数据

  2. 代码更简洁:不需要在 SearchRequest 中定义接收 Builder 的构造器

  3. 更直观:构建过程直接操作最终对象

自定义实现一个预创构建者:

步骤:步骤:

  1. 目标类(Product):定义一个需要构建的类,包含多个属性,并提供空构造器(或者有参构造器,但通常空构造器即可,因为属性将由Builder设置)。

  2. 在目标类中定义静态内部Builder类:这个Builder类将负责构建目标类的实例。

  3. 在类中定义静态方法获取Builder实例

  4. 在Builder类中预先创建目标类的实例:使用一个private final字段在Builder类内部预先创建目标类的实例。

  5. 定义构建方法:为每个需要设置的属性提供方法,这些方法会设置预先创建的目标实例的对应属性,并返回Builder实例本身(用于链式调用)。

  6. 定义build()方法:返回预先创建的目标实例。注意,由于是直接返回同一个实例,因此多次调用build()方法将返回同一个实例。如果希望每次build返回新实例,则不能使用预创建模式,而需要在build时复制对象。

  7. (可选)添加参数验证:在设置属性方法或build()方法中添加必要的参数验证。

  8. (可选)提供复制方法:提供一个静态方法,用于从现有目标实例创建Builder实例,以便复制和修改


public class Student {
    private String name;

    private String age;
    private String where;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", where='" + where + '\'' +
                '}';
    }

    public Student() {
    }
    public Student(String name, String age, String where) {
        this.name = name;
        this.age = age;
        this.where = where;
    }
    public static Builder builder(){
        return new Builder();
    }
    public static class  Builder{
       private final Student student = new Student();
        public Builder name(String name){
            this.student.name = name;
            return this;
        }
        public Builder age(String age){
            this.student.age = age;
            return this;
        }
        public Builder where(String where){
            this.student.where = where;
            return this;
        }
        public Student build(){
            return this.student;
        }
    }
}