我有一个包含许多实例字段的(Java)类(其中许多是可选的)。我希望所有字段(因此类)都是不可变的。所以,我想使用Builder Pattern来构造类的实例。
我可以使用Builder模式配置myBatis来创建类的实例吗?我知道我可以让myBatis返回一张地图并使用该地图在我的代码中构建实例。但是,我正在寻找一种方法来配置这种映射(或使用一些约定),类似于如何通过使用Java Bean和构造函数来创建实例。
修改(包含示例)
以下是一个例子:
package com.example.model;
// domain model class with builder
public final class CarFacts {
private final double price;
private final double numDoors;
private final String make;
private final String model;
private final String previousOwner;
private final String description;
public static class Builder {
// required params
private final double price;
private final String make;
private final String model;
// optional params
private final String previousOwner;
private final String description;
private final double numDoors;
public Builder(double price, String make, String model) {
this.price = price;
this.make = make;
this.model = model;
}
public Builder previousOwner(String previousOwner) {
this.previousOwner = previousOwner;
return this;
}
// other methods for optional param
public CarFacts build() {
return new CarFacts(this);
}
}
private CarFacts(Builder builder) {
this.price = builder.price;
//etc.
}
}
然后,我有一个mapper:
<!-- this doesn't work but I think h3adache suggest that I could have the resultType
be com.example.model.CarFacts.Builder and use the Builder constructor. But I'm not sure how
I would call the methods (such previousOwner(String)) to populate optional params -->
<mapper namespace="com.example.persistence.CarFactsMapper">
<select id="selectCarFacts" resultType="com.example.model.CarFacts">
select *
from CarFacts
</select>
</mapper>
最后,我有mapper界面:
package com.example.persistence.CarFactsMapper;
public interface CarFactsMapper{
List<CarFacts> selectCarFacts();
}
我还希望能够通过myBatis使用静态工厂方法创建实例。例如:
public final class Person {
private final String lastName;
private final String firstName;
private Person(String lastName, String firstName) {
this.lastName = lastName;
this.firstName = firstName;
}
public Person newInstance(String lastName, String firstName) {
return new Person(lastName, firstName);
}
}
具体来说,我怎样才能让myBatis调用newInstance(String,String)?
答案 0 :(得分:-1)
您无需使用构建器或静态工厂方法。是的,如果你试图保持不变性这些模式肯定是帮助,因为突变可能发生,我们应该说'在实例之间',例如因为构建器在调用build()之前发生了变异(以创建一个新的不可变实例)。
但是,不变性与给定实例的构造方式无关。它不会让我们在任何地方为可变的类编写构造函数和静态工厂方法。在构造点上,所有对象都尚未发生变异,因此真正重要的是接下来会发生什么(在建造者和工厂离开之后)。
你需要做的就是专注于类本身,并认为这个类是不可变的。常规的myBatis映射应该没问题 - 节省编写构建器的时间。
所以 - 你的类是不可变的,是的,因为你的所有字段都是final,而且是原始类型或String(在Java中是不可变的!)。如果你有其他非原始字段,那么你希望它们是最终的(技术上你不需要写最终但是建议,只要该字段从未实际重新分配)并且你希望他们的类跟随这些规则的递归一直向下。
我希望这会有所帮助,我想要了解的是构建器模式和工厂方法对于管理构造很有用,但是它们不会免费提供不变性,而且总是需要编写构造函数。