越来越多人开始使用Java但是他们大多数人没有做好足够的思想准备(没有接受OO思想体系相关培训)以致不能很好驾驭Java项目甚至导致开发后的Java系统性能缓慢甚至经常当机很多人觉得这是Java复杂导致其实根本原因在于我们原先掌握的关于软件知识(OO方面)不是太贫乏就是不恰当存在认识上和方法上的误区
软件的生命性
软件是有生命的这可能是老调重弹了但是因为它事关分层架构的原由反复强调都不过分
一个有生命的软件首先必须有一个灵活可扩展的基础架构其次才是完整的功能
目前很多人对软件的思想还是焦点落在后者完整的功能觉得一个软件功能越完整越好其实关键还是架构的灵活性就是前者基础架构好功能添加只是时间和工作量问题但是如果架构不好功能再完整也不可能包括未来所有功能软件是有生命的在未来成长时更多功能需要加入但是因为基础架构不灵活不能方便加入死路一条
正因为普通人对软件存在短视误区对功能追求高于基础架构很多吃了亏的老程序员就此离开软件行业带走宝贵的失败经验新的盲目的年轻程序员还是使用老的思维往前沖其实很多国外免费开源框架如ofbiz compiere和slide也存在这方面陷阱貌似非常符合胃口其实类似国内那些几百元的盗版软件扩展性以及持续发展性严重不足
那么选择现在一些流行的框架如HibernateSpring/Jdonframework是否就表示基础架构打好了呢?其实还不尽然关键还是取决于你如何使用这些框架来搭建你的业务系统
存储过程和复杂SQL语句的陷阱
首先谈谈存储过程使用的误区使用存储过程架构的人以为可以解决性能问题其实它正是导致性能问题的罪魁祸首之一打个比喻如果一个人频临死亡打一针可以让其延长半年但是打了这针其他所有医疗方案就全部失效请问你会使用这种短视方案吗?
为什么这样说呢?如果存储过程都封装了业务过程那么运行负载都集中在数据库端要中间JEE应用服务器干什么?要中间服务器的分布式计算和集群能力做什么?只能回到过去集中式数据库主机时代现在软件都是面向互联网的不象过去那样局限在一个小局域网多用户并发访问量都是无法确定和衡量依靠一台数据库主机显然是不能够承受这样恶劣的用户访问环境的(当然搞数据库集群也只是五十步和百步的区别)
从分层角度来看现在三层架构表现层业务层和持久层三个层次应该分割明显职责分明持久层职责持久化保存业务模型对象业务层对持久层的调用只是帮助我们激活曾经委托其保管的对象所以不能因为持久层是保管者我们就以其为核心围绕其编程除了要求其归还模型对象外还要求其做其做复杂的业务组合打个比喻你在火车站将水果和盘子两个对象委托保管处保管过了两天来取时你还要求保管处将水果去皮切成块放在盘子里做成水果盘给你合理吗?
上面是谈过分依赖持久层的一个现象还有一个正好相反现象持久层散发出来开始挤占业务层腐蚀业务层整个业务层到处看见的是数据表的影子(包括数据表的字段)而不是业务对象这样程序员应该多看看OO经典PoEAAPoEAA 认为除了持久层不应该在其他地方看到数据表或表字段名
当然适量使用存储过程使用数据库优点也是允许的按照Evans DDD理论可以将SQL语句和存储过程作为规则Specification一部分
Hibernate等ORM问题
现在使用Hibernate人也不少但是他们发现Hibernate性能缓慢所以寻求解决方案其实并不是 Hibernate性能缓慢而是我们使用方式发生错误
最近本人正搞一个项目项目中我们用到了struts+hibernate 由于关系复杂表和表之间的关系很多在很多地方把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
Spring分层矛盾问题
Spring是以挑战EJB面貌出现其本身拥有的强大组件定制功能是优点但是存在实战的一些问题Spring作为业务层框架不支持业务层Session 功能
具体举例如下当我们实现购物车之类业务功能时需要将购物场合保存到 Session中由于业务层没有方便的Session支持我们只得将购物车保存到 HttpSession而HttpSession只有通过HttpRequest才能获得再因为在Spring业务层容器中是无法访问到 HttpRequest这个对象的所以最后我们只能将购物车保存到HttpSession这个功能放在表现层中实现而这个功能明显应该属于业务层功能这就导致我们的Java项目层次混乱维护性差 违背了使用Spring和分层架构最初目的
领域驱动设计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和设计模式一样不是一种新的理论而是实战经验的总结它将前人 使用面向模型设计的方法经验提炼出来供后来者学习以便迅速找到驾驭我们软件项目的根本之道