Design patterns 工厂模式创建预构建的构建器
我有一个Design patterns 工厂模式创建预构建的构建器,design-patterns,Design Patterns,我有一个SearchRequest对象,可以使用SearchRequestBuilder创建它。一些预定义的SearchRequestBuilder可能非常复杂。我见过工厂模式用于创建同一父对象的不同类型,但我想知道这样的设计是否合适: public class SearchRequestBuilderFactory { public enum Type { SEARCH, MATCH } public SearchRequestBuilder cre
SearchRequest
对象,可以使用SearchRequestBuilder
创建它。一些预定义的SearchRequestBuilder
可能非常复杂。我见过工厂模式用于创建同一父对象的不同类型,但我想知道这样的设计是否合适:
public class SearchRequestBuilderFactory {
public enum Type {
SEARCH, MATCH
}
public SearchRequestBuilder createBuilder(Type type) {
switch (type) {
case SEARCH:
return createSearchBuilder();
break;
case MATCHING:
return createMatchBuilder();
break;
}
}
private SearchRequestBuilder createSearchBuilder() {
SearchRequestBuilder srb = new SearchRequestBuilder();
srb.addField("*");
srb.addFilter("searchFilter");
return srb;
}
private SearchRequestBuilder createMatchBuilder() {
SearchRequestBuilder srb = new SearchRequestBuilder();
srb.addFilter("matchFilter");
srb.addThreshold(0.5);
return srb;
}
}
看起来是个好办法 也许您想封装
SearchRequestBuilder
的配置逻辑,以便
- 更好的单元可测试性
- 降低圈复杂度
interface SearchRequestBuilderConfigurer {
public void configure(SearchRequestBuilder srb);
}
class DefaultSearchRequestBuilderConfigurer implements SearchRequestBuilderConfigurer {
public void configure(SearchRequestBuilder srb){
srb.addField("*");
srb.addFilter("searchFilter");
}
}
class MatchSearchRequestBuilderConfigurer implements SearchRequestBuilderConfigurer {
public void configure(SearchRequestBuilder srb){
srb.addFilter("matchFilter");
srb.addThreshold(0.5);
}
}
封装配置逻辑后,可以使用映射而不是switch语句
public class SearchRequestBuilderFactory {
public enum Type {
SEARCH, MATCH
}
private Map<Type, SearchRequestBuilderConfigurer> type2Configurer = new HashMap<Type, SearchRequestBuilderConfigurer>();
public SearchRequestBuilderFactory(){
type2Configurer.put(Type.SEARCH, new DefaultSearchRequestBuilderConfigurer());
type2Configurer.put(Type.MATCH, new MatchSearchRequestBuilderConfigurer());
}
public SearchRequestBuilder createBuilder(Type type) {
SearchRequestBuilderConfigurer configurer = type2Configurer.get(type);
if(configurer == null){
throw new IllegalArgumentException("type " + type + " is not supported");
}
SearchRequestBuilder srb = new SearchRequestBuilder();
configurer.configure(srb);
return srb;
}
private SearchRequestBuilder createSearchBuilder() {
SearchRequestBuilder srb = new SearchRequestBuilder();
srb.addField("*");
srb.addFilter("searchFilter");
return srb;
}
private SearchRequestBuilder createMatchBuilder() {
SearchRequestBuilder srb = new SearchRequestBuilder();
srb.addFilter("matchFilter");
srb.addThreshold(0.5);
return srb;
}
}
公共类SearchRequestBuilderFactory{
公共枚举类型{
搜索、匹配
}
私有映射type2configuer=newhashmap();
公共SearchRequestBuilderFactory(){
type2configuer.put(Type.SEARCH,新的defaultSearchRequestBuilderConfigure());
type2configuer.put(Type.MATCH,new matchSearchRequestBuilderConfigure());
}
公共SearchRequestBuilder createBuilder(类型){
SearchRequestBuilderConfigurer=Type2Configuer.get(类型);
if(configurer==null){
抛出新的IllegalArgumentException(“不支持类型”+type+);
}
SearchRequestBuilder srb=新的SearchRequestBuilder();
configurer.configure(srb);
返回srb;
}
私有SearchRequestBuilder createSearchBuilder(){
SearchRequestBuilder srb=新的SearchRequestBuilder();
srb.addField(“*”);
srb.addFilter(“搜索过滤器”);
返回srb;
}
私有SearchRequestBuilder createMatchBuilder(){
SearchRequestBuilder srb=新的SearchRequestBuilder();
srb.添加过滤器(“匹配过滤器”);
srb.addThreshold(0.5);
返回srb;
}
}
PS:您也可以使用(又称虚拟构造函数)而不是配置器。没有构建器工厂的限制。但它们并不常见是有原因的 只要对象的属性对其构造不是强制性的,我们就使用生成器。我不知道你的申请是否如此。因此,我将尝试给出一个涵盖所有场景的正确答案 场景1:某些类成员仅在特定模式下使用。在这种情况下,实际的类需要划分为不同的类。在您的情况下,如果属性阈值永远不会是搜索请求的一部分,那么它不应该是SearchRequest类的一部分,您应该有一个MatchRequest类来保存它 场景2:所有属性都在使用中,但在特定模式下,其中一些属性将具有常量值,我们永远不会对其进行外部更改。在这种情况下,我们使用不同的构建器(带有继承),而不是工厂。这将限制这些属性在外部的可访问性,这是强制性的
场景3:所有属性都在使用中,但在特定模式下,其中一些属性将具有预定义值,这些值可能会在外部发生更改。在这里,我建议使用与2相同的解决方案,因为它比使用工厂更具可读性、可维护性和可维护性。例如,在您的例子中,让我们假设传递给addField()的值需要更改为“.”,传递给addThreshold()的值需要更改为“1.5”,这样两个开发人员就可以完成这些更改,而不必接触同一个类。看起来是一种合理的方法。