不要向上层暴露本层以及所依赖的接口细节

h1.背景

在攻略全文搜索中,搜索的接口很丰富,并且将来可能会增加更多的需求。搜索业务类提供的接口既要能满足将来的扩展,
又不能暴露底层的细节,还要避免功能组合带来接口的膨胀。

h1.设计方法
搜索接口的依赖关系,如下图:
前端控制器 ----> 搜索业务方法 --> QP搜索API

QP主要需要一下参数控制搜索条件:
普通的: key=key
指定字段搜索: search_in=field
按照月份过滤: travelmonths=month
飘红: hl=true,hl.fl=highlightFields,
hl.simple.pre=飘红开始标签
hl.simple.post=飘红结束标签

h2.不好的设计1
如果Service层像控制器层提供一个functionParams,让Controller根据
不同的情景设置不同的参数进行搜索:

public SearchBookBean searchBooks(String key, Map<String,Object> functionParams)

这样可以满足接口扩展的功能,但是这样就把控制器层依赖QP的接口参数,qp参数变化会跨层影响控制层。

所以最好再提供一个封装,让QP对于控制器层透明。

h2.不好的设计2
常用的方式,对不同的条件封装出不同的接口,这样可能就会有:
普通的搜索:

public SearchBookBean searchBooks(String key, boolean highlight){
//1.根据普通搜索需要的参数设置到functionParams
Map<String, Object> functionParams = new HashMap<String,Object>();
if(highlight){
addhighlightParams(functionParams);
}
//2.调用public SearchBookBean searchBooks(String key, Map<String,Object> functionParams)
return searchBooks(key,functionParams);
}

同样对于只在作者中搜索:

public SearchBookBean searchBooksOnlyUserName(String key, boolean highlight){
Map<String, Object> functionParams = new HashMap<String,Object>();
if(highlight){
addhighlightParams(functionParams);
}
functionParams.put("search_in", "userName");
return searchBooks(key,functionParams);
}

然后同样会有按照月份过滤:

public SearchBookBean searchBooksWithMonthFilter(String key,int month, boolean highlight){
//...
}

然后还会有只在作者中搜索并且按照月份过滤...
这样接口就会组合性的增长。

h2.Best practice

比较好的方法是能够抽象出一个动态组合各种功能的东东来搞定这个。

class SearchFunction {
private Map<String,Object> functionParams;

public SearchFunction(){
functionParams = new HashMap<String, Object>();
}

public SearchFunction withOnlyUserName(){
functionParams.put("search_in", "userName");
return this;
}

public SearchFunction withMonthFilter(int month){
functionParams.put("travelmonths", month);
return this;
}

public SearchFunction withDefaultHighlight(){
List<String> highlightFields = new ArrayList<String>();
highlightFields.add("title");
highlightFields.add("travelRoute");
highlightFields.add("destCities");
return withHighlight(highlightFields);
}

public SearchFunction withHighlight(List<String> highlightFields){
functionParams.put("hl", true);
functionParams.put("hl.fl", StringUtils.join(highlightFields,','));
functionParams.put("hl.simple.pre", "<span class=\"colOrange\">");
functionParams.put("hl.simple.post","</span>");
return this;
}

public Map<String,Object> getFunctionParams(){
return functionParams;
}
}



这样我们就可以定义一个接口来搞定所有的需求:

public SearchBookBean searchBooks(String key, SearchFunction function){
Map<String, Object> functionParams = null;

if(function == null){
functionParams = new HashMap<String,Object>();
}else{
functionParams = function.getFunctionParams();
}
return searchBooks(key, functionParams);
}

控制器就可以动态的组合各种功能了:
普通带飘红搜索:

SearchFunction sf = new SearchFunction();
sf.withDefaultHighlight();
SearchBookBean searchBean = service.searchBooks("keyword", sf);

复杂一些的搜索: 只在作者中搜索并且按照月份过滤带飘红的搜索

SearchFunction sf = new SearchFunction();
sf.withOnlyUserName().withMonthFilter(1).withDefaultHighlight();
SearchBookBean searchBean = service.searchBooks("keyword", sf);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值