我可以使用Builder模式配置myBatis来创建类的实例吗?

时间:2013-03-28 16:08:23

标签: java mybatis builder-pattern static-factory

我有一个包含许多实例字段的(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)?

1 个答案:

答案 0 :(得分:-1)

您无需使用构建器或静态工厂方法。是的,如果你试图保持不变性这些模式肯定是帮助,因为突变可能发生,我们应该说'在实例之间',例如因为构建器在调用build()之前发生了变异(以创建一个新的不可变实例)。

但是,不变性与给定实例的构造方式无关。它不会让我们在任何地方为可变的类编写构造函数和静态工厂方法。在构造点上,所有对象都尚未发生变异,因此真正重要的是接下来会发生什么(在建造者和工厂离开之后)。

你需要做的就是专注于类本身,并认为这个类是不可变的。常规的myBatis映射应该没问题 - 节省编写构建器的时间。

所以 - 你的类是不可变的,是的,因为你的所有字段都是final,而且是原始类型或String(在Java中是不可变的!)。如果你有其他非原始字段,那么你希望它们是最终的(技术上你不需要写最终但是建议,只要该字段从未实际重新分配)并且你希望他们的类跟随这些规则的递归一直向下。

我希望这会有所帮助,我想要了解的是构建器模式和工厂方法对于管理构造很有用,但是它们不会免费提供不变性,而且总是需要编写构造函数。