Author: 江南白衣
为什么, SpringSide不这样设计?
Hibernate已经很好的承担了dao的角色,所以项目一开始可以摈弃dao,直接使用Manager类。当遇到特殊情况时,可以把某Manager类内部拆分成dao和Manager。注意,即使拆分也是内部进行的,使用该Manager类的Controller或者other Manager 使用的仍然是Manager的接口,重构不会对它们造成影响。
RoR里一个Domain Object 已经等于 Java里的POJO+Dao Interface + Dao Implement + Manager Interface + Manager Implement
因此,Java里也未必在每种情况里都要按照最伟大最正确的指引把这5个类写全了。
使用接口是仅仅因为Spring和Rod推荐吗? 更需要具体的理由:
1) 为了多种Implement的并存?
为了多种Dao实现的并存和切换? 必要时把Dao层和Service层分离已能做得很好,不需要再加接口。
而Service实现之间的切换? 暂时BookManager有另一个实现的可能性不高。如果真的碰到多个策略类的情况,大家都懂得去重构抽取接口,这是设计基本功,不需要人推荐。
2) 为了反射,Proxy,AOP?
Java的Interface才支持Proxy?但这种语言级的限制比较让人不服气。更倾向于用cglib来解决问题,比如Spring的AOP,cglib的效率甚至比动态Proxy更高,比如EasyMock,JMock们也以支持cglib来创建mockObject.
所以,我们一般只有多种实现、策略类、多重继承这些原本就该使用Interface才重构抽取接口,而不是不管三七二一早早一字排开。
如SpringSide选型所述,选用Spring MVC是因为它最易入门,特征见Spring MVC之写给在用其他MVC框架的程序员入门
一直认为Spring MVC的设计水平是最接近凡人地界的,所以对它又爱又恨。SimpleFormController错在一点都不simple,但又没有Webwork那样在Servlet中建造一个模式漂亮的绝对空间。在我眼里SimpleController 功能不够强,学习曲线又不低....
当然,它也不是一无是处,用小小的框架自动完成对象绑定之类的动作还是不错的,所以我把一些东西抄了出来,抄到multi-action中。
另,Struts不符合Pragmatic路向,不予考虑。
考虑到推广Spring MVC的阻力,我们同时支持了WebWork。
Rod的<Professional J2EE with Spring>的Sample代码即是纯Mock风格。这种风格不依赖Spring与ApplicationContext,完全绝对的分层开发。但缺点是完全的白盒测试,对于普通团队来说成本比较高,需要手工注入所有依赖bean,手工设置所有出场对象的方法和假定返回值,代码量非常巨大,而且这种Mock UT离实际环境很远,仍然需要再写一套集成测试的Test Case。
所以,对业务代码,为了快速开发,我们还是尽量使用带集成测试性质的单元测试方案。
仅在需要限定分离解耦某些对象时,才重载public String[] getConfigLocations()函数限定applicationContext,使用EasyMock Mock对象(见BookManagerMockDaoControllerTest.java)
不过,对SpringSide-Core这样API级的代码时,就怎么Mock都不为过了。
全部抽取为Properties固然有:
1.伟大的多语言特质。
2.最大限度避免编码问题。
但是,这个抽取的过程一定有开发进度的代价的。
而且国内团队的英文命名水平,给代码阅读和管理带来的不便。
还有Properties文件及内容也需要管理。
而,UTF-8编码后编码问题已不大。多语言特征也只在论坛这种国际通用产品型项目上比较有意义,对于占更大多数方案型项目意义不大。
所以SpringSide是UTF-8编码,适当演示 i18n用法而不是整个项目强迫使用。 像Commons-Validator这种全部demo和约定用法都是i18n的情况,我们还特别demo出不用i18n的情况,省得有些团队不会自己做减法。
把JSP放在WEB-INF下,的确可以避免用户绕过Controller直接访问jsp,但会造成IDE在开发时不能自动跳转浏览JSP了,因此我们开发时JSP仍然放在外面,在部署时才把jsp移进WEB-INF 并修改springmvc-serverl.xml中的映射配置。
至于在xml里配置jsp路径,我觉得放在哪里配置都是利于一方而不利于另一方了, Struts Ti 的第2阶段不是也要废掉xml config file么?作为程序员,我更喜欢把路径写在Controller的顶端,方便程序员。