`
iamlotus
  • 浏览: 108188 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

空接口能做些什么?

阅读更多

自从有了接口的概念后,OO编程都推荐面向接口编程。根据“如非必要,勿增实体”的原则,通常我们定义(或重构出来)的接口都是有行为的,很少用空接口。那么空接口有什么用呢?
一个接口定义了两方面,类别和特征。比如


public interface Animal{

         void eat();

         void sleep();

}


定义了类别Animal,它的特征是:可以eat和sleep。如果我们不关心sleep,这个接口就变成


public interface Animal{

         void eat();

}



这两个Animal描述的是现实中的同一类别,只是关心的角度不同,抽取出的特征也不同。

更进一步,如果连eat这个特征我们都不关心,这个接口就变成了一个空借口


public interface Animal{ 

}




定义这样一个借口相当于阐述以下事实“尽管现在不关心动物具体有什么特征,但本接口的存在说明系统中动物和非动物是有区别的,以后也可能会用到这些区别”。

这样,Tree不用实现Animal,但Dog应该实现Animal。空命名接口的存在对类的设计给出了约束,即方便了以后扩展,也让后来者理解代码更加方便。可以认为是“代码即文档”的一种体现。



-------------------------------------------------------------------------------------------------------------------------

在通常的业务系统中,分页查询是非常常用的功能。对这样的查询,在用Toplink(Hibernate应该也一样)实现时一个最佳实践是不用对象,而用SQL实现。

假设User包括id,name,birthday,gander,department,isActive几个属性,在“维护用户”界面上需要分页显示id,name,birthday,gander。那么DAO不要返回一个Page对象给Service,而应该自定义一个PagingUserResult

public class PagingUserResult{

         private String id;

         private String name;

         private Date birthday;

         private Gander gander;

         //.. Getter and Setter

}

并返回Page<PagingUserResult>给Service。这是因为

1)Toplink组装对象的时间比较长,特别是如果在UnitOfWork中作这件事,每个User会被Clone一份到UnitOfWork中,整体时间消耗要多不少。

2)分页功能牵涉的数据量是比较大的,如果User组装成对象,一旦翻上几页,这些实际不会操作到的对象就会把缓存中的User都挤出缓存,使得缓存命中率非常低,使得用缓存不如不用。

所以,设计框架时要求分页查询都用ReportQuery,不允许出现直接返回Page<User>给Service的情况。当然,这样的规范必须通知Service的实现者。这可以通过文档,code review等方式,不过最好的方法是在框架中尽量杜绝Service这样作的可能性,这时候空接口就派上作用了。

 

首先定义一个空接口

public interface QueryResult{
}

由于具体的QueryResult(比如PagingUserResult)就是个Bean,所以QueryResult没有共同行为,只是一个标识作用。

然后,定义Page接口

 

public interface Page<T extends QueryResult> {
    T get(int index);     
     //.... other functions
}

 

这里,通过泛型表达了“Page只能容纳QueryResult”,由于User是Domain对象,不会实现QueryResult,自然不可能被放到Page中了。

 

当然,由于Page只是一个接口。为了使用方便,框架还要提供一个PageBuilder,这里是一个大概的样子

public class PageBuilder<T extends QueryResult> {
       private List<T> contents=new ArrayList<T>();
       public PageBuilder<T> add(T content) {
        contents.add(content);
        return this;
    }
       public Page<T> buildPage(){
         // You may need a inner class which implements Page<T> here

      }
}

 

总结一下,结合空接口QueryResult和泛型,我们避免了developer以后由于不了解而误用的情况。

类似的,也可以让Domain对象实现一个叫作Entity的空接口,可以规范DAO的使用,避免像DAO中传入非Domain的Class。

 

3
0
分享到:
评论

相关推荐

    wsdl生成客户端、wsdl接口测试及简介(有网络和无网络)

    - **服务做些什么**:指服务提供的具体操作或方法。 - **如何访问服务**:包括数据格式、通信协议等。 - **服务位于何处**:即服务的地址,通常用URL表示。 这些属性共同构成了Web服务的核心信息,帮助开发者了解和...

    PHP支付接口WAP版源码,微信个人收款二维码+支付宝收款,支付宝即时到账免签约接口.rar

    增强恶意空单拦截,有效应对恶意客户拦截传递过程中的订单信息后提交空单行为 6、升级优化邮件系统内核到最新 7、对空间要求更宽泛,只要空间支持PHP就能使用,支持绝大多数的PHP空间 8、相关提示更加人性化,...

    java笔试和面试的时候要注意些什么问题啊,大概有些什么问题要问.docx

    - `NullPointerException`,当试图访问空引用时抛出。 18. **err 和 exception的区别**: - `System.err` 通常用于输出错误信息。 - `Exception` 是所有异常类的基类。 19. **List, Set, Map是否继承自...

    超级有影响力霸气的Java面试题大全文档

    HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。 HashMap允许将null作为一个entry的key或者...

    java 面试题 总结

    HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。 HashMap允许将null作为一个entry的key或者...

    2022学Java的面试都会问些什么-.docx

    - 运行时异常是程序运行时可能出现的错误,比如空指针异常,无需在方法签名中声明。 - 一般异常(检查异常)则需要在方法中声明抛出,否则编译不通过。 5. **Servlet的生命周期**: - 每个Servlet实例在服务器...

    微机课程设计

    答:一般从CPU的NMI端引入的中断为非屏蔽中断,它不受中断允许标志IF的影响,其类型号为2,系统中只能有一个非屏蔽中断,CPU不论在做什么事,都会响应些中断,它一般用来处理系统的重大故障。 一般从CPU的INTR端...

    摩托罗拉C++面试题

    这样,你就能一次又一次地使用该方案而不必做重复劳动."上述定义是对设计模式的广义定义.将其应用到面向对象软件的领域内,就形成了对设计模式的狭义定义. 可以简单的认为:设计模式就是解决某个特定的面向对象软件问题...

    C#面试基础知识汇总.doc

    哪种更好些?为什么? - **强类型**:类型在编译时确定,更安全可靠。 - **弱类型**:类型在运行时确定,灵活性高但可能引入错误。 - 强类型通常被认为更优,因为它减少了运行时错误的可能性。 #### 31. 什么是反射...

    支付宝+微信竞价单页订单系统自适应手机端源码

    11、增强支付宝付款接口,在支付宝业务调整,免签接口失效后,本店第一时间升级了订单系统,提供了收款码收款(支付宝收款码获取方法及替换方法见附送的 WORD 文档)及支付宝商户(即时到账、担保交易)双接口,方便...

    WFPHP订单系统 WAP手机版 v2.0.zip

    10、增强支付宝付款接口,在支付宝业务调整,免签接口失效后,本店第一时间升级了订单系统,提供了收款码收款(支付宝收款码获取方法及替换方法见附送的WORD文档)及支付宝商户双接口,方便买家根据自己的需求切换...

    v4l2驅動篇.pdf

    除了這些基礎接口外,V4L2 API 中還包含了編碼和效果設備的 stub,雖然這些功能尚未完全確定,但其目的是轉換視頻數據流。此外,還包括了 “teletext” 和 “radiodatasystem” 的接口,這些接口目前在 V4L1 API 中...

    Java基础入门教程 第6章 集合框架(共28页).ppt

    `ArrayList`是实现`List`接口的一个具体类,它是一个动态数组,支持快速随机访问,但插入和删除元素相对慢些。`ArrayList`的构造方法有多种,可以为空、基于现有集合或预设大小。 在Java中,`String`类是不可变的,...

    PYTHON in action

    关于所要求的对象我们需要知道些什么? - **对象概念**:了解wxPython中的各种对象,如`wx.App`、`wx.Frame`等。 - **对象的作用**:每个对象都有其特定的功能,如`wx.App`用于管理整个应用程序的生命周期。 ####...

    局域网winxp共享一键修复

     我们可能还会遇到另外一个问题,即当用户的口令为空时,即使你做了上述的所有的更改还是不能进行登录,访问还是会被拒绝。(如用administrator账号,密码为空时)这是因为,在系统“安全选项”中有“账户:使用空白...

    IP的安全監控和遠端監控應用需要考慮的技術及要素

    PTZ代表Pan(左右旋轉)、Tilt(上下傾斜)和Zoom(變焦),這些攝影機能夠進行全方位運動,適用於需要覆蓋更大範圍或需細節放大查看的場景。 ##### 日夜兩用型網路攝影機 這種攝影機能在低光照條件下工作,通常配...

    韩国人手机上的J2ME手机游戏哈里波特源代码

    韩国人手机上的J2ME手机游戏哈里波特源代码,运行于LG手机,因些声音方面需要LG特有的API,如果你没有LG的SDK的话,可以建立一个空接口,游戏目前在SJBOY下可以正常运行,但是没有声音。图片资源请在jar包里提龋

    產銷履歷標籤列印程式.zip

    在《產銷履歷標籤列印程式》中,開發者可能利用了.NET框架中的System.Drawing命名空間,該命名空間提供了圖形編程接口,可以方便地進行圖形绘制、圖像處理和打印操作。通過創建Graphics對象,開發者能夠在標籤模板上...

    ez18k16k12k编程器软件.rar

    不过,我们可以根据文件名“SPEZ18K_110630”做些推断。"SPEZ"可能是编程器型号的前缀,"18K"再次确认了该编程器与18K容量的芯片有关,而"110630"可能是软件版本号或发布日期,表示2011年6月30日。 在IT行业中,...

Global site tag (gtag.js) - Google Analytics