J2EE的最佳实践
设计从简单开始,扩展从重构开始优秀的设计是什么?并不是在初期就具有弹性,而是把业务压缩在若干个模型中,然后使用一套简单实用的接口让这些模型相互协作起来.扩展是什么?扩展是保持结构的松散,并非去支持有可能存在的逻辑.套用于后者的扩展通常会破坏抽象的原子性.使得一个抽象无法集中精力去做自己的事.我以为spring时代脱去架构师的黄金甲,用一套标准,实用,简单的框架结构为软件设计提供了一套简单明了的解决方案.设计者完全不必要从整体上去衡量设计的合理性,核心工作转变为需求到模型的抽象.
认真对待每一个异常不要把异常认为是可以恢复的,当异常产生的时候要做"发生异常应该做的事",不要把异常当成一个变相的if/else,在里面写业务逻辑.
数据访问中缓存的策略 坚持做最有效的缓存!何为最有效的缓存?在业务结构中越靠上的缓存,价值越明显.但是不是所有的缓存都能提高质量的.只有一些读频繁但是写不频繁的对象才是最有缓存价值的对象.因为任何的缓存都会破坏数据,对象的一致性.并且会带来许许多多的隐藏问题.使用缓存一定要先确认被缓存的对象是否有cache的价值.
让事务发挥价值
事务存在的背景:
Data Access when multi object operate on the database
keep the procession in a atomicity
to make sure the data stay in a consistence state
通常为什么要使用事务?套用一个英文短语比较容易让人理解--"unit work".也就是说一个事务应该专注于一个业务流程.诸如删除用户和删除用户其他信息,假如只删除了用户但是删除其他信息失败了这不能算是一个完整的业务流程.应该把这个需求抽象成事务.
数据会话的时间要短而频
数据库表的设计要OO化OO表设计的最终目的是饱和OR框架的Mapping机制,最大程度上体现组件的reuse.OO的成熟模型都可以抽象到数据库表里,eg.接口,抽象类,继承,多态,包括各种设计模式.一个足够OO的数据库可以从表的命名上看出来.
把配置文件当成资源直接部署到容器里
这样做的好处是,一旦配置被部署到容器中,则变成了一个全局的资源,这些资源由容器统一维护,这样会具有如下的灵活性
1:全局调用,由容器维护
2:方便处理分布式需求,
3:解除与辅助类之间的耦合
4:用j2ee的标准协议取代私有协议数据访问策略中最不成熟的连接:manytomany
我的立场,绝对不使用多对多的连接.一个多N:N的关系带来的性能损失是1*N.为核心对象划分状态和身份
这一点在多线程的开发中是非常有意义的.
最佳的实践是使用与业务有关的键值来实现equals()和hashCode().
以Hibernate为例,如果你在Session外比较对象,你必须要实现equals()和hashCode()。在Session内部,Java的对象识别可以值得信赖。如果你实现了这些方法,不要再使用数据库辨识!瞬时对象不具有标识值,Hibernate会在对象被保存的时候赋予它一个值。如果对象在被保存的时候位于Set内,hashcode就会变化,要约就被违背。为了实现用与业务有关的键值编写equals()和hashCode(),你应该使用类属性的唯一组合。记住,这个键值只是当对象位于Set内部时才需要保证稳定且唯一,并不是在其整个生命周期中都需要(不需要达到数据库主键这样的稳定性)。绝不要在equals()比较中使用集合(要考虑延迟装载),这些相关联的类可能被代理过。
Session会不时的向数据库同步持久化状态,如果这种操作进行的过于频繁,那么性能会受到一定的影响。有时候你可以通过禁止自动flushing尽量最小化非必要的flushing操作,或者更进一步,在一个特殊transaction中改变查询和其它操作的顺序。
在三层结构中,考虑使用saveOrUpdate()
当使用一个servlet/sessionbean的架构的时候,你可以把已加载的持久对象在sessionbean层和servlet/JSP层之间来回传递。使用新的session来为每个请求服务,使用Session.update()或者Session.saveOrUpdate()来更新对象的持久状态。
在两层结构中,记得自己关闭session.
当仅仅使用servlet的时候,你可以在多个客户请求中复用同一个session,只是要记得在把控制权交还给客户端之前disconnect掉session。
为了得到最佳的可伸缩性,数据库事务(Database Transaction)应该尽可能的短。但是,程序常常需要实现长时间运行的“业务事务(Application Transaction)”,包含一个从用户的观点来看的原子操作。这个业务事务可能跨越多次从用户请求到得到反馈的循环。请使用离线对象(Detached Object),或者在两层结构中,把Hibernate Session从JDBC连接中脱离开,下次需要用的时候再连接上。绝不要在一个Session中包含多次业务事务,否则你的数据可能会过期失效。对于关联优先考虑异步 面向客户的时代,对于那种用户接口频繁因为读取数据过慢而导致假死的现象的解决方案被提到手头,基于b/s的Ajax可以通过异步调用先把界面返回给用户,在后台用线程读取.早在ajax之前也可以使用activexObect来实现类似的功能,其目的只有一个,不要把dirty的界面丢在客户面前.其实解决这一问题的方案还有很多种,包括JMS,Laze loading等.
面向接口的编程习惯
现代化软件已经基本上摆脱了一个人搞定一套系统的旧模式,讲究的是协作.但是协作中,不同设计风格上的差异致使效率降低,java接口的标准规范了协作的流程,为团队开发引入了和谐的软件环境.使用接口,不仅仅兼容了各种设计风格,而且解除了调用上依赖关系.最大的吸引更在于,新时代的开源框架对于接口形式的业务提供了简单明了的支持.包括Aop,webservices等