`
hanzhicheng754
  • 浏览: 8048 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类

反思DAO

阅读更多
反思DAO

1.DAO模式带来的困惑
    OO语言和关系型数据库在表达数据的方式上,存在着天然的阻抗性。所以才会有DAO模式的出现。最为正统的DAO,包括接口、具体实现类,及工厂。然而现在,由于Spring 等IOC容器的出现,对正统的DAO模式有了很大的影响。工厂早已被Spring取代(其实两者都实现了我们使用工厂的目的),剩下的就只剩接口和实现类了。我们在学习正统的DAO模式的同时,又困惑于实际开发时,DAO模式早已大变身,早已和书中说的不一样了。我想,在现在这种MVC+DAO的开发范式中,DAO层,是一个让人非常纠结的层,很头疼。每个实体对象都需要一个DAO与之对应,同时每个DAO做的事情又都是如此的相似,无非就是些CRUD操作。有了Spring之后,我们做的事情就更少了,无非是把真正的操作委托给Spring的Template。于是很多人想到,可以定义一个共用的DAO,来完成所有的CRUD操作。我们会纠结在这两种方式中,有人觉得一个CommonDAO就够了,有的人觉得我们需要一个单独的一层来管理DAO。
    不知道大家是否和我一样,充满困惑, 心中有着许多的节,总是觉得有什么地方不妥,却也非常无奈!在此,我谈谈我的看法,希望和大家交流思想,希望得到更好的解答。
2.我们是否还需要为DAO定义一个接口? 
    DAO接口是否还有存在的意义呢,这个问题,我们还是先回到DAO模式本身来看吧。DAO模式的存在,是为了给应用程序的上层,提供一个面向对象的,稳定的接口,处理对象到关系型数据库的转换。有了这样一个稳定的接口的存在,使得我们在设计的时候,可以不用考虑关系型数据库的存在,而更加的关注于业务逻辑本身(很肉麻的一句话,又有几个人是这样做的)。这样的思想,和DDD中Repositories有异曲同工之妙。但是,要达到这种目的,并非就得定义一个接口层!DAO模式不是银弹,并不是所有的程序,都需要我们耗费巨大的精力去维护一个DAO层。在我们设计一个应用程序的时候,程序的复杂性是否需要我们使用DAO模式呢?不知道有多少架构师在设计时考虑过这些问题(虽然我还不是)。而采用Martin在书中描述的那样,将这些操作集成到实体对象中。或者,只是提供DAO的实现类,不需要接口,因为程序没有那么复杂,即使将来,程序扩展需要,再抽象出接口层出来,也不会是一件困难的事情。为什么,我们国内的项目,一上来就是MVC,一上来就是DAO模式呢?
    当然,有些时候,你不得不定义一个接口层。比如,你是发布一个产品,一个可以支持多个数据库的产品,或者,你的程序有多个数据源,这样,我们花如此大的精力,来维护一个DAO层的意义也就体现出来了。此时,你就会体会到封装和多态给我们带来的好处了!面向抽象编程的本质不就是封装一切可变的,使得我们依赖于一个相对不变的东西吗?
3.CommonDAO和DAO层
    当我们纠结于这个问题时,我们还是静下心来好好分析下,这两种方式有什么不同吧?
    1.相同点:两种方式,我们的目的都是可以达到的,完成需要的功能。
    2.如果使用CommonDAO,相对于传统的方式,会给我们的程序带来什么样的影响呢?增,删,改就没什么好说的了,最大的不同应该是查询。由于业务逻辑的复杂性,不同的实体,往往会有不同的查询要求。这样的话,如果我们真的想用一个DAO来搞定这些查询的话,就会遇到很大的挑战,这里我们有两种方式可以选择。一种是调用DAO的上层提供SQL,这种方式,可能是国内很多人采用的方式吧!这种方式从设计的角度来看,应该是一种糟糕的设计,他已经背离了我们使用DAO模式的初衷----隔离数据存储的细节。这种方式,会将关系型数据库所带来的复杂性蔓延到整个系统中,不但使得软件没有一个清晰地结构,而且依赖的关系发生了倒转,下层依赖上层,无形中增加了系统的复杂性。不管是需求变更,还是后期的维护,都会是一场噩梦。SQL本身的标准化,使得这种影响相对的减小了,但在我们实际开发过程中还有一个绕不过去的坎,在这里却是凸显了出来,那就是分页查询,每个数据库支持的方式都不一样!设想一下,如果开发的中途,客户说Oracle太贵了,买不起,我们要改用SQLServer,会发生什么样的事情?不管怎么说,编程从此不再快乐,这是肯定的!有过这种经历的人应该不少,反正我自己是深有体会!我们在使用Java这种面向对象的语言,切换数据库能带来那么大的影响?除非你的程序只是在用Java传递SQL,否则你应该自豪的告诉别人,我们用的是OO的语言,不就是换个数据库嘛,小意思(当然这些话,是不会对客户说的 )!如果客户最终要用MySQL怎么办?因为他听说MySQL不要钱啊,天啊,我要跳槽了,不如Kill Me吧!另一种方式就是不用SQL了,改用HQL,在SQL之上,抽象出来一个查询语言,由程序决定该怎么翻译。这种方式相对于前一种方式来讲,算的上是一大种进步(当然,不用你自己去翻译)。因为,采用这种面向对象的查询语言,不仅相对容易理解,而且,达到了我们一个目的,就是封装会变化的东西,使得我们依赖于可以看做不变的东西。这样,像切换数据库,或者支持多个数据库这样的事情,我们程序员都会乐呵呵的做这些事情,有了像Hibernate这样的工具,确实,使得我们的生产力得到了大大的提高。当然这种方式依然是不完美的,结构问题,依赖倒置的问题依然存在。好在,查询不会是业务领域的核心逻辑。目前为止,我们得出的结论应该是,要使用CommonDAO,就得使用HQL这种可以面向对象的查询语言。我们可以用现成的,也可以自己去创造,如何选择,我想不言而喻。使用第二种方式还有一个挑战,就是动态查询。要解决这个问题确实不是一件容易的事情。从目前我所了解的方式来看,一个是iBatis的Dynamic查询,另一种就是Hibernate的Criteria。第一种方式,需要一个Map参数。从OO的角度来看,这种变相的结果集方式,早已失去了Java这种强类型语言的类型检查的优势,不过确实是解决问题的一个一个好办法(虽然SQL还是得自己去拼)。这种处理方式早以赢取了许多程序员的芳心。让我们再来看看Hibernate的处理方式。Hibernate虽然考虑到了这一点,但是确有很多不如人意的地方。一来,Hibernate本身的实现就不够完美,另一方面,在使用Spring之后,会有些问题。因为要使用Criteria,必须要Hibernate原生的Session,但Spring给我们的确是他封装过的Session,这样你使用Criteria时,就会产生类型转换的问题,所以即使Hibernate本身,也不推荐我们使用Criteria。不知道老外是不是很少做这样的事情,反正国内的项目查询的条件总是一大堆,纠结的很,很多时候,会感觉整个系统除了查询没别的什么功能了。老外没搞好这事,不知道我们国人中有没有想做这方面贡献的,反正我翻遍JavaEye没发现。可能很多人心中有些想法,只是没时间实现吧。这玩意,我也想过,抖出来让大家看看。(不过已经有老外把这事给搞定了,Google的 Warp Framework,我知道这事后,很兴奋,跑网吧去想下源代码回来学习,可惜没找到)思路很简单,就是利用Annotation,实现这个动态查询。先说下为什么我觉得对Java来讲,这样的方式是最好的。这种方式离开了Hibernate不行,还要定义一堆的Query Object。所以我也纠结的很,不知道自己做这么到底意义有多大。代码也写了一半,我想大家照着这个思路下去,都可以做成。做Web开发,还有一个绕不过去的地方就是MVC,例如我们最常用的Struts1,必须为每个Form定义一个FormBean。现在有一种思路就是FormBean里面再定义一个对象VO,将Formbean的职责委托给VO。我希望的是,这个VO就是我们需要的Query Object,在每个属性上,加上对应的Annotation,在CommonDAO中,我们只需在通用的动态查询方法中解析VO里面的Annotation,然后拼成HQL,传递给Hibernate执行,返回结果就行。我想,我们应该可以做出一个可以满足大部分需求的HQL生成工具出来,也能让PG心里觉得我们的技术不是很落后,Annotation,jsut cool !当然这里你可以直接用FormBean这个VO,但我的固执狂的劲又上来了,下层的结构又依赖上层的结构了,还分层做什么?所以我选择这种方式。我只是提供一种思路 ,希望能有更好的方式!
    3.CommonDAO和传统的DAO还有一个很大的不同,这个问题就是责任泛化!我不知道责任泛化这个词是谁发明的,应该跟契约式设计有关系!当然,这不仅仅是一个设计的问题。是否,每个实体都需要更新功能?是否每个实体都可以删除?如果不是,但是你却给客户端程序那样做的能力!最小责任化,也即我们最常挂在嘴边的,编程,简单就是美!
    4.传统的DAO模式,接口加子类,最让现在的我们诟病的应该就是你要为每一个实体提供一个DAO。
4.总结
    还是那句话,没用银弹,没有完美的解决方式!每种技术本身都有其优缺点,没有最好,只有选择的问题!作为程序员,特别是对一个软件的架构有发言权的人,更应该保持一刻平静的心,在合适的时候,做合适的选择。
分享到:
评论

相关推荐

    实验5 过滤器、监听器以及MVC + DAO设计模式应用开发实验源代码(1-4).rar

    在本实验中,我们将深入探讨Java Web开发中的关键概念,包括过滤器(Filter)、监听器(Listener)以及Model-View-Controller(MVC)和Data Access ...记得在实践中不断反思和优化,这样你的编程能力将会得到显著提升。

    区块链和去中心化自治组织 (DAO):公司的演变?-研究论文

    DAO 代表了对组织(例如公司)如何构建和运行的彻底反思,包括所有权、治理、决策和利润分配的变化。 DAO 不仅显着降低了交易成本——交易成本是公司存在的真正原因——通过使用智能合约,它们可以防止法律和其他...

    java课程设计报告-个人通讯录管理程序.doc

    此外,还可以反思设计的优缺点,对未来改进提出建议。 通过这个课程设计,学生能够深入理解Java编程语言,掌握面向对象设计原则,以及如何使用Java Swing或JavaFX构建图形用户界面。同时,还会了解如何使用数据库...

    02.课程设计报告模板.docx

    总的来说,这个课程设计报告全面涵盖了从项目规划到实施的各个环节,要求学生不仅展示编程技能,还要具备良好的团队协作和自我反思能力。通过这样的实践,学生能够更好地理解和应用面向对象编程的理论,为将来的工作...

    J2EE设计模式课程设计项目程序和课程设计报告

    课程设计报告通常包含项目的概述、需求分析、系统架构设计、具体实现细节、测试计划及结果,以及项目反思和改进点。报告应详尽地记录了开发过程,便于评估和学习。 5. **病历资料管理系统**: 这一系统可能包括...

    学号_姓名_实验报告(模板)1

    在飞机大战游戏的设计与实现中,使用了多种设计模式来优化代码结构,提高代码的可维护...在反思实验过程时,学生应关注如何更好地将理论知识转化为实际应用,以及如何在遇到新问题时灵活运用已知的设计模式来解决问题。

    实训作业基于javaweb的订单管理系统源码+数据库+实训报告.zip

    实训报告应包含项目的目标、设计思路、技术选型原因、系统功能介绍、实现过程、遇到的问题及解决方案等内容,是学习和反思的重要部分。 5. **源码结构**: "code"文件夹很可能包含了项目的全部源代码,其中包括但...

    实验报告3

    【实验报告3】主要关注的是Web网站设计与开发的基础知识,特别是通过构建一个购物网站系统来实践这些技能。实验目标集中在以下几个...同时,实验也强调了理论知识与实践的结合,以及在解决问题过程中的反思和自我提升。

    android课程设计报告.doc

    学生们需要利用Java编程语言设计应用的各个组件,包括数据模型公共类、Dao公共类、DBOpenHelper.java类,以及特定的DAO类如InaccountDAO.java,包含相应的构造方法和CRUD(Create、Read、Update、Delete)操作。...

    网上书店.rar

    实训总结则是一份对整个项目的反思和经验总结,对提升个人技能和团队合作有着重要意义。 至于`shopping702pm`,这可能是项目的主要源码目录,里面可能包含了所有的Java类、配置文件、静态资源等。在STS(Spring ...

    洗衣管理系统(java+SQL server)

    - 报告通常包含系统的需求分析、设计决策、实现细节、测试结果和未来改进方向等内容,是项目实施过程的总结和反思。 通过这个洗衣管理系统项目,学生可以深入理解Java编程、数据库设计和管理、以及软件开发的整体...

    数据库技术及应用课程设计

    4. 数据访问对象(DAO)或ActiveX数据对象(ADO):VB6.0中与数据库交互的两种常见方式,DAO是早期的数据库访问技术,而ADO更现代,提供了更快的数据访问速度和更好的兼容性。 5. 数据绑定:将VB6.0中的控件与...

    J2EE企业级项目开发-1期 任务3-1 实训项目单.doc

    4. **总结归纳与实训报告**:完成项目后,学生需要反思和总结整个实训过程,撰写实训报告,记录遇到的问题、解决方案以及个人收获。 实训评估标准包括: 1. **系统设计要求**:项目需满足功能需求,能正常运行,占...

    java课设 servlet班级管理web系统(完成)+报告.zip

    11. **报告**:项目完成后,开发者通常会编写报告,总结项目目标、设计思路、实现技术和遇到的问题及解决方案,这对于学习和反思整个开发过程至关重要。 综上所述,这个Java课设展示了如何使用Servlet和JSP来构建一...

    当当网购书系统--JAVA开发

    【标题】"当当网购书系统--JAVA开发"是一个基于JAVA技术栈的电子商务项目,旨在模拟实际中的在线购书流程,提供用户浏览、...尽管项目可能存在不足,但它为学习者提供了一个实践和反思的机会,有助于提升实际开发能力。

    软考高项论文范文-项目进度管理.docx

    - 模型层是数据访问层DAO与Hibernate的结合。 - 数据库层功能使用Oracle数据库实现。 - 通过Websphere架构实现业务逻辑处理。 - 机票订单的生成和审核流程由Domino进行驱动。 #### 四、项目进度管理方法与策略 ...

    java后端1年经验和技术总结

    例如,创建一个包含增删改查等通用方法的DAO基类,可以减少重复代码。 - **继承与多态**:继承允许子类继承父类的属性和方法,而多态则使得子类对象可以被视为父类对象。利用多态特性,可以实现灵活的代码设计。...

    J2EE程序员必读书籍:Expert One-on-One J2EE Development without EJB

    - **DAO 设计模式**:书中详细解释了 DAO(Data Access Object)设计模式的实现方法及其优点。 - **数据访问层的最佳实践**:包括如何选择合适的持久化技术(如 Hibernate)、如何处理数据库连接池等问题。 ##### 6...

    七年语文问题训练单1.docx

    D、絮叨(xù dao) 解析:四个选项中,只有A项"侍弄"的拼音标注不正确,应为"shì nòng"而非"si nong"。 2、词语解释: A、喜出望外:遇到意想不到的好事而感到非常高兴,不是“向外张望”。 B、憔悴:形容人...

    学生宿舍管理系统C#程序设计

    详细设计阶段将专注于每个功能模块的具体实现,包括数据库设计、DAO(数据访问对象)和DTO(数据传输对象)的设计。 编码和实现阶段,作者会将设计转化为实际的代码,确保各模块功能的正常运行。测试环节则用来验证...

Global site tag (gtag.js) - Google Analytics