`

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

阅读更多
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);
分享到:
评论

相关推荐

    1层架构-MOOC课程内容.pdf

    一个典型的多层客户端-服务器架构,例如网络应用的分层模型,展示了如何通过各层暴露接口(API)供上层调用。在这样的模型中,每层既充当服务器的角色,向上层提供服务,又作为客户端去调用下层服务。最底层,即网络...

    计算机系统设计原理(英文)

    - **定义:**抽象是一种隐藏实现细节并只暴露必要接口的方法。它有助于减少不必要的复杂性,使得设计更加清晰。 - **层次抽象:**在计算机系统设计中,通常采用多层抽象的方法,每一层都隐藏了下一层的复杂性,仅...

    Android_Camera分析

    - **libui.so**:该库在Camera架构中扮演核心角色,主要提供Camera类的接口,向上层应用暴露Camera功能。它封装了复杂的底层细节,简化了开发者的使用体验。 - **libcameraservice.so**:作为Camera的服务器端,它...

    个人笔记--JAVA基础

    - **封装**是指隐藏对象的实现细节,只暴露必要的接口。封装提高了代码的安全性和可维护性。 **3.3. 继承extends** - **3.3.1. super关键字** - 用于访问父类中的方法或属性。 - **3.3.2. Object** - 所有Java...

    SOA概念、技术与设计

    - **服务封装**:服务内部的具体实现应该被封装起来,只暴露必要的接口供外部访问。 - **服务标准化**:使用标准的协议和技术栈来构建服务,以确保互操作性和可扩展性。 #### 四、SOA的应用场景 - **企业内部系统...

    JAVA程序设计课后习题及答案3.pdf

    3. **封装**:封装是面向对象编程的核心原则之一,它隐藏了类内部的实现细节,只暴露必要的公共接口供外部使用。通过封装,可以增强代码的安全性,减少对外部的依赖,并提高代码的可维护性。 4. **继承**:继承允许...

    Java语言编程规范--华为技术有限公司(2001年发布)

    Java语言编程规范是软件开发中的重要指南,它旨在提高代码质量、可读性以及团队间的协同效率。华为技术有限公司在2001年发布的这份规范,不仅反映了当时业界的最佳实践,也体现了华为对于软件工程严谨性的重视。以下...

    面向对象oop详解

    封装隐藏了对象的内部细节,只保留一些对外的接口,通过接口可以进行数据的读取和修改操作。在Java等OOP语言中,通过四种访问控制修饰符:private、default、protected、public,来控制类成员的可见性。private修饰...

    面向对象的系统集成测试概述.pdf

    接口定义了对象间的交互方式,封装则是将对象的实现细节隐藏,仅暴露必要的功能。继承允许子类继承父类的属性和方法,多态则允许不同对象对同一消息作出不同的响应,增强了代码的灵活性和复用性。 面向对象技术的...

    java基础知识笔记总结

    - 封装是把数据和操作数据的方法封装在一起,隐藏对象的内部细节,只暴露必要的接口。 8. **访问修饰符** - 访问修饰符包括public、protected、default和private,用于控制成员的可见性。 9. **类的设计分析** ...

    java后端面试问题

    - **封装**: 封装是指隐藏对象的具体实现细节,仅暴露必要的接口供外部使用。在Java中,封装主要通过访问修饰符(如public、private、protected等)来实现。例如,类的成员变量通常设置为private,而通过public的...

    实验三Java类的继承与派生

    2. **封装**:将对象的内部实现细节隐藏起来,只暴露必要的公共方法供外部调用。 3. **多态**:允许子类对象直接赋给父类变量,使得同一类型的对象在运行时展现出不同的行为特征。 #### 类的继承 在Java中,类的...

    JavaScript面向对象编程指南

    - **封装**:隐藏对象的具体实现细节,只暴露必要的接口。 - **继承**:子类可以继承父类的属性和方法,并且可以在不影响父类的前提下扩展功能。 - **多态**:同一个行为在不同的类中可以有不同的实现方式。 ### 二...

    Java程序员基础知识汇总

    封装隐藏对象的内部实现细节,只暴露必要的接口;继承允许创建新类,这些新类继承现有类的特性和行为;多态允许子类对象可以被当作父类对象使用;抽象用于定义接口或部分实现的类,强调“做什么”而不是“怎么做”。...

    java面试资料大全(非常全面)

    - 封装性:隐藏对象的实现细节,只暴露必要的接口。 - 继承性:允许类继承父类的特性。 - 多态性:允许子类重写父类的方法,使得同一接口具有多种形态。 - 抽象性:通过抽象类或接口定义通用行为。 23. **Java...

    JAVA知识点列表 JAVA知识点列表

    - 封装是将数据和操作这些数据的方法绑定在一起,隐藏对象的内部细节,只暴露必要的接口。 - 提高了代码的安全性和可维护性。 - **类的定义方法**: - 类是具有相同属性和行为的对象的模板。 - 类定义包括类名...

    中南大学软件学院SOA复习重点

    (3) **松耦合可编排:** 服务之间通过标准的接口进行交互,减少了服务之间的依赖关系,使得服务更容易维护和扩展。 ##### 3. SOA的典型优势 (1) **分布式异构系统的集成与互操作:** SOA提供了一种机制,可以轻松...

    软件工程试题大全

    - **信息隐蔽**:每个模块只暴露必要的接口,并隐藏其实现细节。 - 不属于软件工程原则的是**自底向上**,它是一种开发方法而非基本原则。 #### 十二、模块的概念 - 模块是**数据说明**、**可执行语句**等程序对象...

    java初级知识

    封装是指隐藏对象的内部状态和实现细节,仅通过公开的接口与外部交互。 **8. 访问修饰符** Java支持四种访问级别:`public`, `protected`, `default`(无修饰符), `private`。 **9. 类的设计分析** 在设计类时,...

Global site tag (gtag.js) - Google Analytics