2013-03-28 208 views
8

我有一个(Java)类与许多实例字段(其中许多是可选的)。我希望所有的领域(因此类)都是不可变的。所以,我想用Builder模式来构建类的实例。我可以配置myBatis以使用Builder模式创建类的实例吗?

我可以配置myBatis以使用Builder模式创建类的实例吗?我知道我可以让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. 
} 
} 

然后,我有一个映射器为:

<!-- 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> 

最后,我映射器接口:

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(字符串,字符串)?

回答

-1

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

尽管如此,不变性与给定实例的构造方式无关。它不会让我们在任何地方为可变的类编写构建器和静态工厂方法。在构建时,所有对象都没有发生变化,所以真正重要的是接下来会发生什么(建设者和工厂离开后)。

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

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

我希望这会有所帮助,我希望得到的一点是,构建器模式和工厂方法对于管理构造是有好处的,但它们不会为您提供免费的不变性,而且您始终需要编写构造函数。

+0

这不回答这个问题。 –

相关问题