文档章节

谈谈应用层切面设计

悠悠然然
 悠悠然然
发布于 2016/01/19 14:31
字数 4589
阅读 6206
收藏 181
点赞 26
评论 35

AOP概要理解纠偏

说到AOP,这个东东现在已经不是一个新词汇了,我们拿一下百度词条来看看是下面的样子的:

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

但是今天我要说,这个定义太过狭义,实际上AOP的概念要比上面的定义要宽泛得多,今天我就给大家来扯扯AOP的事儿。

从AOP这三个单词来看,它的定义还是非常准确的,就是面向切面编程。但是后面的这一堆解释:

通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

这明显是鬼扯了,明显是把一种具体的实现作为它定义,这就有点“白马即马”的意思了。

主要的变化就是把中间一段与具体的实现有关系的部分去掉。

通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。

这一段太过狭隘,已经远远不能满足软件技术发展的需要了,面向切面就面向切面,与什么预编译的方式有毛关系?与运行期代理有毛关系?与Spring、函数式编程有毛关系?

因此,今天悠然就把AOP的概念重新缕缕:

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过对某一领域进行高内聚低偶合方式进行实现,并通过非偶合的方式与其它业务逻辑进行整合,以对不同切面的实现逻辑进行隔离,从而使得不同领域的实现逻辑之间的耦合度降低,提高程序的可重用性、提高开发效率,同时也大大降低集成与整合难度的一种编程方法。

嗯嗯,虽然不一定严谨,但是比原来的广泛多了,也更能体现AOP的真正意涵。它不仅包含原有定义里的模式,还包含各种各样其它AOP模式,今天悠然就来给大家试着阐述一下。

AOP在软件编程中的应用场景

传统意义上的AOP

传统意义上的AOP,是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,来获得逻辑过程中各部分之间低耦合性的一些隔离效率,比如:常见的应用场景有:

  1. Authentication 权限
  2. Caching缓存
  3. Context passing内容传递
  4. Error handling 错误处理
  5. Lazy loading 延时加载
  6. Debugging 调试
  7. logging, tracing, profiling and monitoring 记录跟踪 优化 校准
  8. Performance optimization性能优化
  9. Persistence 持久化
  10. Resource pooling资源池
  11. Synchronization 同步
  12. Transactions事务
  13. 全文索引
  14. 等等

确实,AOP的应用场景有许多许多,也取得了良好的应用效果,这个已经经过了充分的实践,许多书里也都进行了充分的阐述,这里不再赘述。

非传统意义上的AOP

嗯嗯,今天的重点是这里,别人说得好的地方悠然说不过,因此最好的办法就是不说,悠然说别人不说的地方,这样就压力小多了:)

以下针对@红薯 的猜测纯属臆断,如有雷同纯属巧合:

在正式开始之前,我们来举个实践场景:

@红薯 的开源中国博客1.0

话说,在开源中国的博客列表中,每一篇博客是像下面一样展示的:

从这一块内容中,我们可以看到如下内容:

  1. 原创的图标
  2. 置顶的图标
  3. 博客的标题
  4. 博客的分类
  5. 博客的统计信息30评、2594阅、7赞
  6. 博客的编辑、删除

我们从看到的这些信息里面,可以猜一下@红薯 的表结果是怎么设计的:

表BLOG结构:

  • 博客标识
  • 博客标题
  • 博客标题内容
  • 是否原创
  • 是否置顶
  • 评论次数
  • 阅读次数
  • 获赞次数
  • ....

当然这里应该也有一些其他的字段,我们上面的图片里看不到,我们就当它们不存在。

我们再想想,估计@红薯 还有详细的记录,比如:谁评论的,评论的内容是什么?谁阅读的,是什么时候阅读的?谁点赞的,是什么时候点赞的

于是就有了下面的表:

    评论详情:

  • 博客标识
  • 评论者
  • 评论时间
  • 评论内容
  • ...

    阅读详情:

  • 博客标识
  • 阅读者
  • 阅读时间

    点赞详情:

  • 博客标识
  • 点赞者
  • 点赞时间

嗯嗯,@红薯 仔细想了一想感觉差不多了的样子,这个时候@红薯 缕着他的头发,点上一支烟进入了写代码的酸爽状态。

比如,功能是这样写的:

//博客点赞

保存点赞(博客标识,点赞者标识){
    博客biz.添加点赞(博客标识,点赞者标识);
}

class 博客biz{
     添加点赞(博客标识,点赞者标识){
          博客dao.增加点赞数(博客标识);
          点赞详情dao.增加点赞详情(博客标识,点赞者标识);
     }
}

伴随着一阵阵欢快的噼里啪啦键盘声,开源中国博客1.0 OK了。

@红薯 的开源中国新闻1.0

看着开源中国博客1.0的稳步运行,PV+UV双丰收,@红薯 缕着头发咧着大板牙笑开了花,那就再整个开源中国新闻1.0呗!

于是红薯开始设计表结构:

表NEWS结构:

  • 新闻标识
  • 新闻标题
  • 新闻标题内容
  • 是否置顶
  • 评论次数
  • 阅读次数
  • 获赞次数
  • ....

当然,考虑到新闻也有点赞,也有评语,也有阅读,于是下面的表结构也是需要的:

    评论详情:

  • 新闻标识
  • 评论者
  • 评论时间
  • 评论内容
  • ...

    阅读详情:

  • 新闻标识
  • 阅读者
  • 阅读时间

    点赞详情:

  • 新闻标识
  • 点赞者
  • 点赞时间

嗯嗯,红薯看了下,尼玛除了少个原创,别的都差不多的样子么,但是不一样还是不一样的,那就再做一遍吧,于是一阵阵噼里啪啦之后又搞定了,红薯抹着汗水,再仔细看一下代码,尼玛,怎么这两边的代码几乎一样?感觉哪里有些不对的样子。

管呢,先运行起来再说,哥去泡个妹子放松一下,于是红薯打开了MAC,IPAD,IPHONE7S....

初级AOP方式

运行了一段时间,红薯觉得要加个动态功能,发现要在两边都增加代码,越来越觉得不对劲,于是拿起新买的《企业级JavaEE架构实践》翻看起来,唉当时看书的时候不仔细,这个用切面来解决不是挺好的?

于是红薯把表结构重构了一下:

    评论详情:

  • 评论类型
  • 评论对象标识
  • 评论者
  • 评论时间
  • 评论内容
  • ...

    阅读详情:

  • 阅读类型
  • 阅读对象标识
  • 阅读者
  • 阅读时间

    点赞详情:

  • 点赞类型
  • 点赞对象标识
  • 点赞者
  • 点赞时间

另外增加一个动态表

  • 动态类型
  • 动态对象标识
  • 动态者
  • 动态时间
于是红薯把原来的代码重构了一下,把原来重复做了两遍的的评论、阅读、点赞都抽到了一个里面,然后把原来在业务代码里调用相关评论、阅读、点赞的业务逻辑都抽到了切面当中。嗯嗯,红薯感觉棒极了,脑海中又出现了妹子的身影,对了,IPHONE8P哪里去了?

高级AOP方式

自从引入了切面功能,红薯的工作明显轻松多了,但是唯一不爽的是 随着开源中国的用户越来越多,投资人要求功能方面也要快速推进,现在的红薯几乎已经没有可以缕的头发了,投资人要增加日历、要增加勋章、要增加TAG、要增加提醒,要增加的东西越来越多,同时开源中国的访问者们的眼界又越来越宽了,要求越来越高了,今天这个做的丑了,明天那个做得不人性化了, 红薯开发、测试、发布、切面配置、界面调整、控制层啥都要做,这不又出问题了:


红薯的手习惯的抬起来缕头发了,但是随着OSC功能的增加,头发已经几乎找不到了,红薯狠的把烟屁股拧进烟灰缸,是要彻底解决这个问题了,看起来还得读书啊,再翻企业级JavaEE架构实践,看看有没有啥思路。

Think Big, Start small , Scale Fast.

这是什么鬼?
好的软件是品出来的。
品个屁,现在解决问题才是正点,能不能让我不要每次都改这么多东西?再翻翻目录,看看有啥值得研究的?

仔细看了几遍,红薯的眼睛忽然亮了起来,只要把所有的评论、点赞、评论、动态、以及其它杂7杂8的东西都让它高内聚,低耦合,我做博客只管做博客、做新闻只管做新闻,哪怕再做他多少个,也是仅仅关注我要做的东西,而把这些东西都做成一个个的切面让这些切面去完整的解决这些问题,这样我不就轻松了?原来虽然也引入了AOP技术,但是由于只是初级切面,所以只解决了部分问题,并没有彻底的解决问题。如果我能把切面也切到控制层、界面层,这样就可以真正的做到高内聚、松耦合,而且是真正的业务切面。

技术的切面还是初级的,业务层级的切面才是终级的。

具体实现起来,还是没有什么思路,听听悠然有没有什么思路?

终级解决方案

通过上面对开源中国两个功能模块的分析,我们大致清楚了问题的症结所在,并通过对红薯的心路历程进行分析,大致引入了问题的解决思路,但是真正的落地却不是那么简单的。一个问题的抽象的程度越高,其通用性越好,但是它的易理解程度和易实现程度也就越难。我对实现者面对面多次沟通这个思路时,更多的时候看到的是他们茫然的眼神,以及多次感觉理解了,但是真正实现的时候却又达不到要求,直到许多次反复之后,才慢慢进入状态。

所以我会尽力讲清楚,但是不能保证你一定能理解到我内心所想。

要解决的问题

我们在应用开发过程中,一部分是与具体的业务相关的,另外一部分它与具体的业务并不相关,但是在业务过程中又是有这样那样关系的。如果我们能把这些与具体业务没有直接关系,但又是对业务数据的一种维度的补充或描述能独立出来,想用或不想用仅在一念间,那么这个时候做软件就是一种享受了,而且业务和切面都可以独立变化,而不必考虑彼此的影响。

这个时候从开发效率来说,由于大家各自高内聚低耦合,所以开发、测试、验证、发布都会方便快速许多,集成的时候由于也不必有配置和代码及界面上的协作和引用,这样就可以大大的降低系统集成过程中的开发、测试工作,也避免了由此导致的一系列的可能出现的问题。

那么接下来,我们就用上面分析问题时的例子来阐述,如何解决这个问题,整个实现思路采用Tiny框架相关技术进行解决,非TINY技术平台或框架也是可以实现的,当然实现细节可能会有不同,需要相关的架构师进行相应的调整。

解决问题的思路

每个切面的内容都在自己的业务单元中实现,同时要能在能出来的时候它就能出来。

这里我们就拿上面说的一个场景"评论"来示例

   评论详情:

  • 评论类型
  • 评论对象标识
  • 评论者
  • 评论时间
  • 评论内容
围绕着这个,当可以可以知道它的DAO层代码怎么写,逻辑层代码怎么写(如果是SOA体系还有服务层代码怎么写),最后还有就是界面层的部分。

既然是高内聚低耦合,那当然主是要统一界面的样式。

评价的使用场景一般来说是在显示完主要业务内容之后(如:博客、新闻、文档、软件、etc),可以进行评论,可以进行回复,可以进行引入,当然也要能把已经评论的内容显示出来。

但是需要搞清楚的是,这些内容的展现与人机交互过程明显与不同的业务内容没有一点关系,这也就为进行切面提供了基础。为了便于进行说明问题,这里采用AJAX模式进行解释,虽然采用非AJAX方式也是可以解释得通的,但是应用到的技术的复杂度与解释起来的困难都非常更加复杂。

举个例子,做出来的效果是类似下面的样子:

这个时候,问题就转换为,如何把当前要处理的业务类型和业务数据的标识让评论部分知晓,这个也非常简单,只要用下面的样子写一段模板即可:

#comment("BLOG",blog.blogId)
上面的模板语言是指:现在我是在给一个BLOG类型的业务对象做评论,业务对象的标识是blog对象的blogId属性。

嗯嗯,这个时候较以前的开发,已经省了非常大的工作量了,只是简单的声明一下就可以了。

更进一步的思考

虽然上面的思路已经比较好的解决了问题,但是这里有一个问题:那就是实现时序问题。

也就是说,博客功能是红薯先加的,而评论功能是红薯后加的。这里就出现一个问题:为什么后增加的功能,需要我在已经实现的妥妥的功能要进行调整??这岂不是说,你后面不断的增加功能,我这里都要不断的进行声明?虽然也有一定的道理,但是是不符合好莱坞原则的。实际上也是违反常理的===我是先来的,为什么要为你一个后到的做调整?我根本就不知道你的存在好么?!

出于我们对完美架构的追求以前我们不将就的态度,我们当然要更好的解决此问题。

我们可以在应用当中预设一些扩展点,但是具体扩展些什么东西我是不管的。

这个时候,我们就可以只在界面中增加如下的一段模板语言:

#extendPoint("VIEW","BLOG",blog.blogId)

上面的脚本表示,我这里是一个VIEW类型的扩展点,业务类型是BLOG,业务对象标识是blog对象的blogId属性。

然后由extendPoint决定往里面塞哪些东西。

这个时候,我只要在评论工程里增加如下的配置:

<extend-points>
    <extend-point type="page" order="10">
        #comment(bizType,bizId)
    </extend-point>
</extend-points>
然后如果这个时候,我们又要增加一个留脚印的功能

我们只要增加一个留脚本的功能模块,在这个模块中增加下面的配置:

<extend-points>
    <extend-point type="page" order="9">
        #footprint(bizType,bizId)
    </extend-point>
</extend-points>

总结

通过上面的改进,红薯同学再也不用薅头发了,原有的业务代码再也不用动,这功能居然自动在所有功能中自动出现了。

想到这里,悠然就深深的自责,早点给红薯出主意,红薯同学的一头黑发就留下来了。

当然,上面只是说了一个思想,真正的实现的时候用到的技术还是非常多的:
  • 模块化
  • AOP
  • SOA(如果是互联网应用是需要的,普通的小工程可以不用)
  • 模板语言或类似技术

如果本人没有说清楚,或者读者朋友们没有理解,本人深感自责,也希望同学们能够理解,并在下面的回复博客提问,本人定尽力给出解释。

有喜欢本人博客内容的同学请加关注,以便及时获知本人精品内容!

© 著作权归作者所有

共有 人打赏支持
悠悠然然

悠悠然然

粉丝 2372
博文 184
码字总数 360373
作品 14
杭州
架构师
加载中

评论(35)

悠悠然然
悠悠然然

引用来自“棒子面er”的评论

引用来自“悠悠然然”的评论

引用来自“neo-chen”的评论

没看懂,那些主流的博客,BBS都是 PHP写的。似乎没有 AOP 也占领了半壁江山。
PHP是最好的语言,用不到IOC、AOP、模块化这些Java里的烂概念....

悠然说话真到位
pm168
pm168
好文 79
天生有缘_PAN
天生有缘_PAN

引用来自“random84”的评论

一箭多雕,79
天生有缘_PAN
天生有缘_PAN
79
2006
2006
26
棒子面er
棒子面er

引用来自“悠悠然然”的评论

引用来自“neo-chen”的评论

没看懂,那些主流的博客,BBS都是 PHP写的。似乎没有 AOP 也占领了半壁江山。
PHP是最好的语言,用不到IOC、AOP、模块化这些Java里的烂概念....

悠然说话真到位
Jieven
Jieven

引用来自“悠悠然然”的评论

引用来自“小虫哥哥”的评论

把这么类型的评论,点赞,阅读都塞一起,代码上是省了,性能,个性化,扩张性怎么办?

话说蒸汽机轮船发明出来试航的时候,一帮智者说肯定开不动,开不动——结果船开起来的时候,这些老爷们又说,肯定停不下来,停不下来——
+1 快速开发 性能好不好 并发好不好
悠悠然然
悠悠然然

引用来自“小虫哥哥”的评论

引用来自“悠悠然然”的评论

引用来自“小虫哥哥”的评论

把这么类型的评论,点赞,阅读都塞一起,代码上是省了,性能,个性化,扩张性怎么办?

话说蒸汽机轮船发明出来试航的时候,一帮智者说肯定开不动,开不动——结果船开起来的时候,这些老爷们又说,肯定停不下来,停不下来——

有什么解决方案吗?,望赐教

木有什么方案,我也就会扯扯淡13
小虫0302
小虫0302

引用来自“悠悠然然”的评论

引用来自“小虫哥哥”的评论

把这么类型的评论,点赞,阅读都塞一起,代码上是省了,性能,个性化,扩张性怎么办?

话说蒸汽机轮船发明出来试航的时候,一帮智者说肯定开不动,开不动——结果船开起来的时候,这些老爷们又说,肯定停不下来,停不下来——

有什么解决方案吗?,望赐教
悠悠然然
悠悠然然

引用来自“小虫哥哥”的评论

把这么类型的评论,点赞,阅读都塞一起,代码上是省了,性能,个性化,扩张性怎么办?

话说蒸汽机轮船发明出来试航的时候,一帮智者说肯定开不动,开不动——结果船开起来的时候,这些老爷们又说,肯定停不下来,停不下来——
聊聊视图层切面实现方案

前面发过一篇《谈谈应用层切面设计》,@HulkZ说看了好几遍也没看懂,然后我又拉他到小黑屋面壁思过了好几次;也有人关心个性与扩展性如何得到平衡;也有人说,悠然就会扯淡,如何实现呢?那么...

悠悠然然
2016/05/30
1K
3
bearcat 0.4.1 发布,统一抽象的 model

bearcat 0.4.1 发布了,该版本使用 parseInt 处理 model 默认数值属性。 Bearcat是一个基于自描述javaScript object进行开发的应用层框架, Bearcat提供了一个轻量级的容器来编写简单,可维护...

oschina
2015/03/03
577
0
bearcat 0.3.5 发布

Bearcat是一个基于自描述javaScript object进行开发的应用层框架, Bearcat提供了一个轻量级的容器来编写简单,可维护的javaScripts. Bearcat 提供了一个基础的底层来管理应用逻辑对象,使得开...

fantasyni
2015/01/06
1K
3
JavaScript 应用框架--Bearcat

Bearcat是一个基于自描述javaScript object进行开发的应用层框架, Bearcat提供了一个轻量级的容器来编写简单,可维护的javaScripts. Bearcat 提供了一个基础的底层来管理应用逻辑对象,使得开...

fantasyni
2014/05/13
7K
2
bearcat 0.4.4 更新,添加对 id 冲突的提醒

bearcat 0.4.4 更新,本次更新主要添加对 id 与 bearcat 特殊属性冲突的 warn 提醒,意味着以下写法将得到更加有好的提示 var Tank = function() { this.$id = "async";} module.exports = ...

fantasyni
2015/03/17
691
0
bearcat 0.3.14 发布,优化一致性配置

优化一致性配置 本次升级主要是优化了bearcat提供的一致性配置,之前在把配置依赖注入到bean中,需要指定属性名称为 $V 开头的,现在不需要了,直接用 ${} 占位符的value属性即可 var Car = ...

fantasyni
2015/02/05
1K
3
bearcat a POJOs based application framework for node.js

Bearcat是一个基于POJOs进行开发的应用层框架, Bearcat提供了一个轻量级的容器来编写简单,可维护的node.js. Bearcat 提供了一个基础的底层来管理应用逻辑对象,使得开发者就可以把精力放在应...

fantasyni
2014/05/20
217
0
HTTP 协议 - 简单谈谈 TCP / IP (一)

原文连接 blog TCP / IP 基本概念 世界上几乎所有的 HTTP 协议都是由 TCP / IP 协议来承载的。它是互联网相关的各类协议族的总称(通常所说的规则,就是协议)。 从输入的 URL 里我们可以从中...

三毛丶
2017/07/16
0
0
谈谈应用层网络协议设计

对于初涉网络编程的开发人员来说,在通信协议的设计上一般会有所困惑。一般的网络编程书籍上也较少涉及这方面的内容。估计是觉得太简单了。这块确实是不难,但如果不了解,又很容易出篓子或者...

zhangyujsj
2016/09/13
104
0
spring ioc 和 aop-----一些小结

话说,学习spring也快大半年了,写业务层代码也写了半年之久了,对于spring中的一些核心技术现在还是似懂非懂的,很是纠结啊。。。 最近一直看别人写的对于这一块的理解,于是乎,我有点懂了...

bosscheng
2013/05/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

SpringBoot | 第十章:Swagger2的集成和使用

前言 前一章节介绍了mybatisPlus的集成和简单使用,本章节开始接着上一章节的用户表,进行Swagger2的集成。现在都奉行前后端分离开发和微服务大行其道,分微服务及前后端分离后,前后端开发的...

oKong
今天
2
0
Python 最小二乘法 拟合 二次曲线

Python 二次拟合 随机生成数据,并且加上噪声干扰 构造需要拟合的函数形式,使用最小二乘法进行拟合 输出拟合后的参数 将拟合后的函数与原始数据绘图后进行对比 import numpy as npimport...

阿豪boy
今天
1
0
云拿 无人便利店

附近(上海市-航南路)开了家无人便利店.特意进去体验了一下.下面把自己看到的跟大家分享下. 经得现场工作人员同意后拍了几张照片.从外面看是这样.店门口的指导里强调:不要一次扫码多个人进入....

周翔
昨天
1
0
Java设计模式学习之工厂模式

在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了。 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低耦合度。之...

路小磊
昨天
158
1
npm profile 新功能介绍

转载地址 npm profile 新功能介绍 npm新版本新推来一个功能,npm profile,这个可以更改自己简介信息的命令,以后可以不用去登录网站来修改自己的简介了 具体的这个功能的支持大概是在6这个版...

durban
昨天
1
0
Serial2Ethernet Bi-redirection

Serial Tool Serial Tool is a utility for developing serial communications, custom protocols or device testing. You can set up bytes to send accordingly to your protocol and save......

zungyiu
昨天
1
0
python里求解物理学上的双弹簧质能系统

物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定。假定没有外力时,两个弹簧的长度为L1和L2。 由于两物体有重力,那么...

wangxuwei
昨天
0
0
apolloxlua 介绍

##项目介绍 apolloxlua 目前支持javascript到lua的翻译。可以在openresty和luajit里使用。这个工具分为两种模式, 一种是web模式,可以通过网页使用。另外一种是tool模式, 通常作为大规模翻...

钟元OSS
昨天
2
0
Mybatis入门

简介: 定义:Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。 途径:MyBatis通过XML文件或者注解的形式配置映射,实现数据库查询。 特性:动态SQL语句。 文件结构:Mybat...

霍淇滨
昨天
2
0
开发技术瓶颈期,如何突破

前言 读书、学习的那些事情,以前我也陆续叨叨了不少,但总觉得 “学习方法” 就是一个永远在路上的话题。个人的能力、经验积累与习惯方法不尽相同,而且一篇文章甚至一本书都很难将学习方法...

_小迷糊
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部