`

当前Java软件开发中几种认识误区

    博客分类:
  • java
阅读更多

越来越多人开始使用Java,但是他们大多数人没有做好足够的思想准备(没有接受OO思想体系相关培训),以致不能很好驾驭Java项目,甚至 导致开发后的Java系统性能缓慢甚至经常当机。很多人觉得这是Java复杂导致,其实根本原因在于:我们原先掌握的关于软件知识(OO方面)不是太贫乏就是不恰当,存在认识上和方法上的误区。

软件的生命性

  软件是有生命的,这可能是老调重弹了,但是因为它事关分层架构的原由,反复强调都不过分。

  一个有生命的软件首先必须有一个灵活可扩展的基础架构,其次才是完整的功能。

目前很多人对软件的焦点还是落在后者:完整的功能,觉得一个软件功能越完整越好,其实关键还是架构的灵活性,就是前者,基础架构好,功能添加只是时间和工作量问题,但是如果架构不好,功能再完整,也不可能包括未来所有功能,软件是有生命的,在未来成长时,更多功能需要加入,但是因为基础架构不灵活不能方便加入,死路一条。

  正因为普通人对软件存在短视误区,对功能追求高于基础架构,很多吃了亏的老程序员就此离开软件行业,带走宝贵的失败经验,新的盲目的年轻程序员还是使用老的思维往前冲。其实很多国外免费开源框架如ofbiz compiere和slide也存在这方面陷阱,貌似非常符合胃口,其实类似国内那些几百元的盗版软件,扩展性以及持续发展性严重不足。

  那么选择现在一些流行的框架如Hibernate、Spring/Jdonframework是否就表示基础架构打好了呢?其实还不尽然,关键还是取决于你如何使用这些框架来搭建你的业务系统。

存储过程和复杂SQL语句的陷阱

  首先谈谈存储过程使用的误区,使用存储过程架构的人以为可以解决性能问题,其实它正是导致性能问题的罪魁祸首之一,打个比喻:如果一个人频临死亡,打一针可以让其延长半年,但是打了这针,其他所有医疗方案就全部失效,请问你会使用这种短视方案吗?

  为什么这样说呢?如果存储过程都封装了业务过程,那么运行负载都集中在数据库端,要中间J2EE应用服务器干什么?要中间服务器的分布式计算和集群能力做什么?只能回到过去集中式数据库主机时代。现在软件都是面向互联网的,不象过去那样局限在一个小局域网,多用户并发访问量都是无法确定和衡量,依靠一台数据库主机显然是不能够承受这样恶劣的用户访问环境的。(当然搞数据库集群也只是五十步和百步的区别)。

   从分层角度来看,现在三层架构:表现层、业务层和持久层,三个层次应该分割明显,职责分明:持久层职责持久化保存业务模型对象,业务层对持久层的调用只是帮助我们激活曾经委托其保管的对象,所以,不能因为持久层是保管者,我们就以其为核心围绕其编程,除了要求其归还模型对象外,还要求其做其做复杂的业务组合。打个比喻:你在火车站将水果和盘子两个对象委托保管处保管,过了两天来取时,你还要求保管处将水果去皮切成块,放在盘子里,做成水果盘给你,合理吗?

  上面是谈过分依赖持久层的一个现象,还有一个正好相反现象,持久层散发出来,开始挤占业务层,腐蚀业务层,整个业务层到处看见的是数据表的影子(包括数据表的字段),而不是业务对象。这样程序员应该多看看OO经典PoEAAPoEAA 认为除了持久层,不应该在其他地方看到数据表或表字段名。

  当然适量使用存储过程,使用数据库优点也是允许的。按照Evans DDD理论,可以将SQL语句和存储过程作为规则Specification一部分。

Hibernate等ORM问题
  现在使用Hibernate人也不少,但是他们发现Hibernate性能缓慢,所以寻求解决方案,其实并不是 Hibernate性能缓慢,而是我们使用方式发生错误:

  “最近本人正搞一个项目,项目中我们用到了struts1.2+hibernate3, 由于关系复杂表和表之间的关系很多,在很多地方把lazy都设置false,所以导致数据一加载很慢,而且查询一条数据更是非常的慢。”

  Hibernate是一个基于对象模型持久化的技术,因此,关键是我们需要设计出高质量的对象模型,遵循DDD领域建模原则,减少降低关联,通过分层等有效办法处理关联。如果采取围绕数据表进行设计编程,加上表之间关系复杂(没有科学方法处理、侦察或减少这些关系),必然导致 系统运行缓慢,其实同样问题也适用于当初对EJB的实体Bean的CMP抱怨上,实体Bean是Domain Model持久化,如果不首先设计Domain Model,而是设计数据表,和持久化工具设计目标背道而驰,能不出问题吗?关于这个问题N多年就在Jdon争论过。

  这里同样延伸出另外一个问题:数据库设计问题,数据库是否需要在项目开始设计?
如果我们进行数据库设计,那么就产生了一系列问题:当我们使用Hibernate实现持久保存时,必须考虑事先设计好的数据库表结构以及他们的关系如何和业务对象实现映射,这实际上是非常难实现的,这也是很多人觉得使用ORM框架棘手根本原因所在。

  当然,也有脑力相当发达的人可以 实现,但是这种围绕数据库实现映射的结果必然扭曲业务对象,这类似于两个板块(数据表和业务对象)相撞,必然产生地震,地震的结果是两败俱伤, 软的一方吃亏,业务对象是代码,相对于不容易变更的数据表结构,属于软的一方,最后导致业务对象变成数据传输对象DTO, DTO满天飞,性能和维护问题随之而来。

  领域建模解决了上述众多不协调问题,特别是ORM痛苦使用问题,关于ORM/Hibernate使用还是那句老话:如果你不掌握领域建模方法,那么就不要用Hibernate,对于这个层次的你:也许No ORM 更是一个简单之道: No ORM: The simplest solution
http://www.theserverside.com/blogs/thread.tss?thread_id=41715

Spring分层矛盾问题
  Spring是以挑战EJB面貌出现,其本身拥有的强大组件定制功能是优点,但是存在实战的一些问题,Spring作为业务层框架,不支持业务层Session 功能。

  具体举例如下:当我们实现购物车之类业务功能时,需要将购物场合保存到Session中,由于业务层没有方便的Session支持,我们只得将购物车保存到 HttpSession,而HttpSession只有通过HttpRequest才能获得,再因为在Spring业务层容器中是无法访问到HttpRequest这个对象的,所以, 最后我们只能将“购物车保存到HttpSession”这个功能放在表现层中实现,而这个功能明显应该属于业务层功能,这就导致我们的Java项目层次混乱,维护性差。 违背了使用Spring和分层架构最初目的。

  相关案例:请教一个在完整提交前临时保存的问题:
  http://www.jdon.com/jive/article.jsp?forum=46&thread=28429

领域驱动设计DDD
  现在回到我们讨论的重点上来,分层架构是我们使用Java的根本原因之一,域建模专家Eric Evans在他的“Domain Model Design”一书中开篇首先强调的是分层架构,整个DDD理论实际是告诉我们如何使用模型对象oo技术和分层架构来设计实现一个Java项目。

  我们现在很多人知道Java项目基本有三层:表现层 业务层和持久层,当我们执著于讨论各层框架如何选择之时,实际上我们真正的项目开发工作还没有开始, 就是我们选定了某种框架的组合(如Struts+Spring+Hibernate或Struts+EJB或Struts+JdonFramework),我们还没有意识到业务层工作还需要大量工作,DDD提供了在业务层中再划分新的层次思想,如领域层和服务层,甚至再细分为作业层、能力层、策略层等等。通过层次细化方式达到复杂软件的松耦合。DDD提供了如何细分层次的方式

  当我们将精力花费在架构技术层面的讨论和研究上时,我们可能忘记以何种依据选择这些架构技术?选择标准是什么?领域驱动设计DDD 回答了这样的问题,DDD会告诉你如果一个框架不能协助你实现分层架构,那就抛弃它,同时,DDD也指出选择框架的考虑目的,使得你不会 人云亦云,陷入复杂的技术细节迷雾中,迷失了架构选择的根本方向。

  现在也有些人误以为DDD是一种新的理论,其实DDD和设计模式一样,不是一种新的理论,而是实战经验的总结,它将前人 使用面向模型设计的方法经验提炼出来,供后来者学习,以便迅速找到驾驭我们软件项目的根本之道。

  现在Evans DDD概念很火,因为它将著名的PoEAA进行了具化,实现了PoEAA可操作性,这也是MF大力推崇的原因。最近(8月8日)一位老外博客上用微软的.NET架构和Evans DDD比较的文章:http://weblogs.asp.net/pgielens/archive/2006/08/08/Organizing-Domain-Logic.aspx,这篇文章比较了微软的三层服务应用架构[Microsoft TLSA]和Evans DDD的架构, 使用Microsoft .NET Pet Shop 4为例子,解释两个目标的区别,并且表明
微软是如何在案例中更好地实现支持后者。这篇文章帮助哪些.NET平台上有域设计知识的人实现更好地提高。

  另外一本关于.NET的DDD书籍也已经出版,这些都说明Evans DDD这把火已经烧到.NET领域,当然DDD在Java领域生根开花多年,Evans的DDD书籍就是以Java为例子的,笔者板桥里人也率先在2005年推出DDD框架JdonFramework 1.3版本,这些都说明,Java在整个软件业先进思想的实践上总是领先一步。

参考文章:

面向对象与领域建模

实战DDD(Domain-Driven Design领域驱动设计)

领域模型驱动设计(DDD)之模型提炼

数据库时代的终结

Java EE/J2EE面向对象编程之道

多层架构专题

分享到:
评论

相关推荐

    浅谈JAVA软件开发的几大误区.pdf

    Java软件开发是现代软件行业中广泛应用的一种技术,以其跨平台、高效和安全性著称。然而,在实际的开发过程中,许多开发者存在一些误区,这些误区可能导致软件性能下降、开发效率低等问题。本文将探讨Java软件开发中...

    .net开发中几个重要的认识误区小结

    .NET开发是微软推出的一个全面的软件开发框架,它广泛用于构建各种应用程序。随着.NET的普及,越来越多的程序员开始接触并使用这一技术。但是,在.NET的开发中,存在着一些认识上的误区,以下将对这些误区进行详细的...

    effective-java 配套代码

    2. **单例模式(Singletons)**: 书中讨论了几种实现单例的方式,包括懒汉式、饿汉式、双检锁/双重校验锁(DCL)和静态内部类方式,对比了它们的优缺点和线程安全问题。 3. **构造函数与工厂方法(Constructors and...

    More.Java.Pitfalls中文版

    Java是一种广泛使用的面向对象的编程语言,其强大的功能和跨平台性使其在软件开发领域占据了重要地位。然而,随着复杂性的增加,开发者可能会遇到各种问题和陷阱。《More Java Pitfalls》中文版旨在帮助开发者避免...

    Java算法

    书中提供了许多实用且有趣的示例,旨在帮助新一代软件开发人员、大专院校的师生更好地理解和应用Java算法。 Java算法的应用非常广泛,包括但不限于排序和搜索算法、数据结构的实现、图形算法、加密算法等。Java算法...

    送给编程者的良言警句

    本文将深入探讨IT初学者常见的几个学习误区,并提出有效的解决策略,帮助大家构建坚实的基础,从而在未来的技术浪潮中稳健前行。 #### 误区一:将计算机技术等同于编程技术 很多人,尤其是部分计算机科学与技术...

    100家大公司java笔试题汇总

    - EL (Expression Language) 是JavaServer Pages (JSP) 中的一种简化的脚本语言。 - EL 表达式用于获取JavaBean属性值、执行算术运算等。 **具体解释:** - 选项 C 表示 **`isELIgnored="boolean"` 决定是否支持EL...

    嵌入式系统知识体系、学习误区及建议

    嵌入式系统是一种专用计算机系统,它被设计用于执行特定任务,通常在更广泛的设备或系统中。这个领域涵盖了硬件和软件的结合,是现代科技发展的重要支柱,广泛应用于消费电子、工业自动化、医疗设备、汽车电子、通信...

    有关容器的六大误区和八大正确场景.docx

    以Java应用为例,如Tomcat,其启动过程包括加载WAR文件并启动应用,这可能需要几分钟时间。同时,虚拟机启动速度也在不断优化,如通过减少镜像下载时间等手段,已可达到接近容器启动的速度。因此,启动速度并非容器...

    实用软件单元测试指导

    在单元测试的过程中,存在几种常见的误解,这些误解往往会成为阻碍有效实施单元测试的主要障碍: - **“时间紧迫”误区**:有人认为单元测试会占用大量时间,尤其是在项目进度紧张的情况下,甚至有些开发人员会选择...

    2009年上半年软件设计师下午试题答案

    1. **软件设计基础**:这可能包括了软件工程的基本概念、软件开发过程模型(如瀑布模型、敏捷开发)、软件需求分析、系统设计等。 2. **数据结构与算法**:软件设计师需要掌握基本的数据结构(如数组、链表、树、图...

    2021-2022计算机二级等级考试试题及答案No.14107.docx

    这总结了在MySQL中创建新用户的几种常见方法。 ### 13. PowerPoint动画设置 - **知识点**: PowerPoint中,对于每张幻灯片,并非必须选择一种动画方式。题目中的表述是错误的。这指出了PowerPoint动画设置的一个常见...

    2021-2022计算机二级等级考试试题及答案No.16325.docx

    而“集成测试法”主要是在软件开发阶段用来验证模块间接口是否正确的测试方法,并非直接用于调试的技术。 #### 15. 存储器分类的认识误区 - **知识点概述**:存储器分类的认识误区。 - **详细解析**:存储器一般...

    2021-2022计算机二级等级考试试题及答案No.19899.docx

    根据给定文件的信息,我们可以总结出以下几个重要的知识点: ### 数据库中的实体联系表示法 - **选项解析**:题目询问在数据库中表示实体之间联系的方式。选项中提到了树结构、网结构、线性表以及二维表。正确答案...

    2021-2022计算机二级等级考试试题及答案No.1291.docx

    - **面向对象**:Java是一种完全面向对象的语言,支持封装、继承和多态等特性。 - **跨平台性**:Java程序可以在安装了JVM(Java虚拟机)的任何平台上运行,实现了“一次编写,到处运行”的理念。 - **健壮性**:...

Global site tag (gtag.js) - Google Analytics