`

Java:从AOP之滥觞说起设计师的职责

阅读更多

 

从表面上来看,AOP是个好东西,但是仔细看,发现不是那么美。

 

AOP的不当使用,使代码失去主线索,成为“方面”的分割。而主线索代表了一个产品代码中所围绕的主要概念。

“方面”应该是为“线索”和“流程”服务的,在AOP之前的编程范式中,流程会调用好多基础包完成自己的流程,而AOP之后,无须再调用,自动织入。

其实想想,AOP的织入和普通用的模板模式何其相似,模板模式用的好,效果也非常接近AOP了。你说“业务过程无须再考虑日志的记录,所以日志做成单独的方面比较好”,但是为什么日志不是业务过程要考虑的?什么时候记日志,记什么内容,当然且理所当然是业务要考虑要设计的,这是我的理解,和现代AOP架构部一致的地方。

作为一个设计者,你的每个业务流程,考虑参数检查否?考虑权限判断否?考虑数据库交互否?考虑记日志否?当然都应该考虑,这是完整的过程。可以由上层设计师做成模板模式,由代码实现者只做数据库交互就可以,但是设计上是有全流程的设计的。

那么,如果只对无关紧要的部分使用AOP是否可以?当然是可以的,但是既然已经无关紧要,那么用不用什么心的架构,意义和价值都不大了。

另外,之前的设计过程,某一个业务流程出现错误,只需找特定的一个或几个人负责,现在一个业务涉及到整合的若干个方面,出错了再也要找更多的人来处理,这是小事,但是很烦。

 

从另外一个角度说,你是设计师,你不能总是嫌业务复杂和繁琐,因为这是必然要面对的,逃避不是办法。

 

4
1
分享到:
评论
9 楼 windshome 2013-10-24  


开发者(其实设计者更应该)考虑业务流程之后,用注解和代码其实基本是一致的。


即便使用代码,也不可能长篇大论都在业务流程这里实现(业务流程代理应该是调用其它地方写好的,这是代码分层的概念),肯定是其它地方实现好,业务层调用某个接口的事情。

我反对无原则和节制的使用AOP,其实就是感觉这个东西非高手不易驾驭。

说到权限是系统的可变点,这点我非常赞成。但是有个需要说明的是,需要变动都是因为业务上的需要,对吗?业务上发生变化了,改变业务层的代码不是天经地义的吗?难道非要说业务变化了,代码不需要改变才好吗?

之前我最喜欢重构、AOP这类东西了,以为能够做到,但后来我改变了自己的想法,业务变了,业务层代码就应该改变;存储变了,存储层代码就应该改变,这反而是个最简单的方法。

当然,我说的也有特定的场景,不是所有情况都适用。还是那句话,只是一孔之见,对设计开发,无异于管窥蠡测,当不得真。

8 楼 Shen.Yiyang 2013-10-24  
windshome 写道
非常感谢两位的指点!

其实,我并非多么反对AOP这东西,只是反对滥用。  OracleX 说得好,旧系统改造的确是AOP的一个非常能够发挥作用的场景。

Shen.Yiyang 说的, 在我这里有不同的想法,就是每一个关注点都是业务应该关注的,比如,一个操作应该允许什么登录者来做,什么上下文下才能执行,都应该是业务流程设计者应该考虑的,应该面对的,不能逃避。倒是不管用注解还是代码。


非常感谢两位老兄的观点。其实我的意思,设计者和开发者应该仔细设计自己的流程和代码,想清楚,设计清楚之后,用什么具体代码的组织方式倒是次要的。


开发者确实应该考虑这些方面,但是问题在于开发者用什么样的形式考虑,需要怎样的成本。编程式对一般的开发者来说,始终比AOP高多了,毕竟AOP或者注解只有一个描述,不涉及调用方式。

而对于分离关注点来说,还有个用处在于符合OO原则,就拿你的例子来说,权限的控制,这是系统的一个可变点,如果都和业务写在一起,以后你就会频繁违背open for extension, but closed for modification。
而如果你用编程式方法去做分离,最后你就会有个工厂和容器去管理这些关注点的关系,那这种方式和AOP还有什么区别呢。
7 楼 windshome 2013-10-23  
非常感谢两位的指点!

其实,我并非多么反对AOP这东西,只是反对滥用。  OracleX 说得好,旧系统改造的确是AOP的一个非常能够发挥作用的场景。

Shen.Yiyang 说的, 在我这里有不同的想法,就是每一个关注点都是业务应该关注的,比如,一个操作应该允许什么登录者来做,什么上下文下才能执行,都应该是业务流程设计者应该考虑的,应该面对的,不能逃避。倒是不管用注解还是代码。


非常感谢两位老兄的观点。其实我的意思,设计者和开发者应该仔细设计自己的流程和代码,想清楚,设计清楚之后,用什么具体代码的组织方式倒是次要的。
6 楼 OracleX 2013-10-23  
aop是对面向对象的补充。楼主所说的,所有结果都考虑到当然可以不用aop,只是很多时候不给你时间或机会考虑所有情况。比如在一个旧系统上添加日志等功能,每个技术的存在都有它的合理性。存在即合理
5 楼 Shen.Yiyang 2013-10-23  
一般来说,AOP中的关注点还是和业务无关的吧,使用AOP,不就是为了突出业务的“主线索”,把非业务分离吗。 说到模板模式,个人觉得公共关注点用模板非常不恰当,没有必要讲理由,你可以尝试一下用模板实现统计所有方法调用的参数。 如果为了阅读上,切面和业务能统一起来,我觉得还不如用注解,这样AOP的关注点是注解声明的,业务逻辑是编程式的。
4 楼 windshome 2013-10-23  
谢谢 adaikiss  的回复,其实我当初(2003-2004年)第一次看到AOP的时候,大为惊叹,当时觉得AOP就是我一直想找到的东西,只是后来在工作实践中发现,在实际工作中其实对我帮助不大。


为什么要说是“关注点”,是谁要“关注”,为什么要“关注”?回答这个问题,就说明,其实,所谓的“关注点分离”这个说法是有问题的。所有的关注点,都是因为“要完成业务”这一个基本线索,而共同运转的。为什么不同功能的代码交织在一起?因为业务需要。


其实我的意思并没有多么反对AOP,而且还对之相当有好感,我反对的是AOP的滥用,无非是因为:一定有一个环节,是描述整个业务流程的,业务流程作为主线贯穿代码。

添加新功能、新模块,怎么也离不开业务上需求的变化,因为业务变了,一般都要重新审视之前的设计和实现代码,把变化之后的需求理清楚,是不是AOP倒是小事。关于这个我想说的是,是不是用了AOP,其实相差不大。

另外一个我想表述的是,在我的设计观念中,AOP方式其实和模板模式差不多,甚至不如模板模式好,因为模板模式中,模板那个过程,代表了一个“主逻辑”。


再有,几个我非常想表达的观点,其一就是在一个产品的设计过程中,最困难的工作,最有创造价值的工作,是需求和设计。把三言两语的需求,演化成一种规格说明;把规格说明对应成实现模块的描述,而不是代码;其二,代码阶段省代码量是次要的,逻辑清晰是第一位的。


最后再补一句,好像AOP本身是为高手准备的一种设施,用以提高工作效率,降低系统间的耦合(利器、名剑不是所有人都能玩得好的),而非为庸手准备来逃避写代码的。而真正高手还不一定都喜欢。


一孔之间,仅供参考。




3 楼 adaikiss 2013-10-23  
使用AOP可以根据横切关注点进行模块化,模块间的耦合度非常低,减少重复代码,提高代码的重用率。因为各个关注点都是独立实现的,所以可以避免不同功能的代码块交织在一起,提高可读性和可维护性。
而添加新模块和功能也比普通实现方式来得更简便,只需要实现一个新的关注点即可。
由于各模块是相互独立的,所以在设计和开发阶段可以更灵活,你可以有选择地优先实现一些功能模块,比如可以暂时不实现日志模块和缓存检查模块。并且开发人员也可以更好地进行协作开发,各自只负责自己的模块。
2 楼 windshome 2013-10-23  
以我从业十余年的经历和感受来看,作为设计师,把“少写一些代码”作为一个目标,是不合适的,最应该追求的,是逻辑上清晰、架构上简洁(包括职责明确、肥瘦适中等等)。

作为程序员,也不应当盲目追求少写代码,因为“好的代码”和“行数少的代码”完全不是一个事情。

“好的代码”清晰,包括有清晰的层次、脉络。恰当的使用技术,例如面向对象的继承封装、例如工厂、例如依赖反转,在需要时引入开源代码、开源库让自己解放;到了比较高的层次,由绚烂复归于平淡,代码平淡若水,但是读来清晰,如同娓娓道来在讲述一个故事

“坏的代码”漫无目标、毫无节制和考虑的滥用开源代码和开源库,逻辑和依赖层次混乱,炫耀技术般的导出充斥着设计模式,工厂、单实例;逃避职责般的绞尽脑汁少写几行代码。。。


1 楼 white_crucifix 2013-10-22  
完全同意楼主
很多设计模式的本质是如出一辙的,都是通过子父类的继承关系达到子类逻辑编码过程中在很大程度上的省略,aop也是类似,通过动态代理将某些代码在编译或运行时寄生在主逻辑的上下左右,而达到编码过程中的省略。

相关推荐

Global site tag (gtag.js) - Google Analytics