由整理房间想到的
前几天收拾东西。首先我想把床上的多余的东西移开,放到桌子上。但是桌子上的东西太多了,我得先把桌子上的东西挪一挪。我看到了有个箱子,我想先把桌子上的东西放到箱子里。但打开箱子,箱子里的又是装满了东西。所以,我得先整理下箱子。
于是我想到了Spring。我想,要是有Spring多好啊,当我需要什么的时候,它就给我准备好了,不用我自己去准备了。是的,这就是Spring依赖注入所做的事情。就像炒菜,没有Spring来管理依赖,你得自己买油盐。而有了Spring,你炒菜时吼一吼:“我要油”,油便有了。神说要有油,于是就有了油。
这样的依赖让我们的关注更加集中,干的事情更加单一。 Spring出生之前,人们通过工厂,但那里还不是自动注入。Struts有了自动注入的影子。
注解似乎会成了一种主宰。Java 5对注释的支持有了突破性的增强。越来越多的第三方框架也有了支持注解的版本,如单元测试,如Spring.
之前,我对Spring的注解是持反对态度的,并且个人坚决不用。当时觉得这是与Spring精神相违背的。Spring提倡的是针对接口编程。如果我们想知道对于某个接口,程序中使用的是哪一个实现类,那么,我们只要去Spring的配置文件里找就是了。比如说有一个IUserDAO接口, 在配置文件中我们也许会这样配置:
<bean id=”userDAO” class=”xx.xx.UserDAOJDBC”/>
在这里,我们一目了然的知道用到了这个接口的哪个实现类。如果使用的是注解,我们在UserDAOJDBC类前面加上注解,表明这是一个id为userDAO的bean,那么, 我们要查找的时候,在eclipse中,我们也许得使用Ctrl+H快捷键了。这就带来了查找上的麻烦。还要考虑一种情况。如果这个IUserDAO有两个实现类,一个是UserDAOJDBC, 一个是UserDAOHibernate。这种情况的存在是不令人惊讶的。也许项目刚开始用的是Hiberante, 但后来客户提出了对性能的更高的要求,而所要求的性能已超出hibernate的极限了,那这个时候,就是用jdbc了.又或者,某个公司做了一套产品,卖给不同的客户,不同客户对数据库的要求不一样,所以事先写好两个IUserDAO的实现类,针对不同客户的要求,选择不同的实现,而不用再进行二次开发。这个时候,注解的另一缺点就暴露出来了:不便于修改。
就上面的情况而言,IUserDAO接口有两个实现类, 如果用注释,想要切换实现时,必须得修改源代码。而如果采用配置文件的方式,则只要改配置文件就行了。修改代码的就高境界就是不改代码。
对于查找的问题,spring的另一个提倡观点也算是针对这个缺点的补充:惯例优先。例如对于一个服务, IuserService, 如果有了一套自己的命名惯例,那么,我们就可以直接Ctrl+Shift+T查找这个接口的实现了,比如是UserServiceImpl.java。
注解带来的是开发时的方便。一阴一阳谓之道,开发方便是以牺牲维护的方便作为代价的。开发方便的必然维护麻烦;开发麻烦的必然维护方便。
理论与实际总是有那么些差距。在实际中,我们很少遇到像上面所述的客户要求更改持久层实现的情况。就算有,也许也是三五年之后的事情了。对于那种发生概率很小的事情,我们没必要花太多精力去关注它。我们不会因为火山有可能喷发就不在山脚下住人,我们也不会因为2012有万分之一的可能到来就提前做准备。与其为了一个三五年之后才会发生的维护而在一年的开发时间内都忍受烦琐的配置文件煎熬,还不如无视它进行痛痛快快地开发。
从对Spring注解的抵制到支持的转变,是因为我曾经历过的一个项目。这个项目换过数据库。前期是mysql, 后来改用oracle.我的态度的转变不单是因为这样,还一个就是项目中的国际化。这个项目起初始是用到了国际化的。国际化给开发带来的困难是显而易见的。页面中到处都充斥着诸如user.submit之类的字符,没一个中文。第一,我不敢恭维国人的英语阅读水平;第二,我不敢恭维国人的英语写作水平。所以,有时候,会了知道这个按钮上的是什么文字,开发时还得去找资源文件。后来干掉了国际化,因为考虑到在五年之内,这个项目一不可能跨国二不可能跨洲三不可能跨星球,与其开发如此麻烦,还不如等N年之后要用到国际化时再改。
说到英语读写水平,再扯几句。在《重构:改善既有代码的设计》一书中,作者提倡我们用方法名来消灭注释的存在。有时蛋疼的是,你方法名已经等同于注释的作用了,你还得写注释。举个夸张的例子,有一个方法,方法名叫saveUserInfo(), 完全可以不写注释的,但有人就说:你这个方法是什么意思呀?怎么注释都不写。这不怪人,只怪在于语言的差异。要恨就恨外国人而不是中国人先发明了编程。如果是中国人先发明了编程, 那这个方法名我们就可以写成:保存用户信息()。不用写注释,咱国人都看得懂。哈哈,这时候就得轮到外国人写注释了:/* save user’s information */。