《冒号课堂》连载之十三——切面范式

《冒号课堂》连载之十三——切面范式

3.3  切面范式多角度看问题

横看成岭侧成峰。

——《苏轼·题西林壁》

关键词:编程范式;SoCDRYAOPAspectjoin pointpointcutadviceOOP

  :切面式编程简谈

预览

从宏观角度看,太阳底下没有新鲜事AOP无非是SoC原理和DRY原则的一种应用。

从微观角度看,太阳每天都是新的AOP虽自OOP的土壤中长出,却脱离藩篱自成一体。

抽象是前提,分解是方式,模块化是结果。

在常人眼中复杂的牛体,庖丁经过抽象,已目无全牛,及至提刀分解,自是游刃有余。待牛如土委地,模块化即成。

两条(抽象与分解的原则):单一化,正交化。每个模块职责明确专一,模块之间相互独立,即高内聚低耦合。

对程序员来说,英语也是一门计算机语言,而且是必修的语言。

OOP只能沿着继承树的纵向方向重用,而AOP则弥补了OOP的不足,可以在横向方向重用。

如果一个程序是一个管道系统,AOP就是在管道上钻一些孔,在每个孔中注入新的代码流。

提问

什么是SoCDRY

如何有效地避免紊乱、松散、重复的代码?

抽象与分解的原则是什么?

什么是横切关注点?

接入点与切入点有何区别?

什么是编织?有哪些不同的编织方法?

实施AOP有哪些步骤?

为什么说AOPOOP的一种补充?

为什么提倡尽可能地阅读原文的书籍和资料?

讲解

课间休息刚一结束,引号便重开话题:“OOP方兴未艾,AOP又开始崭露头角。AOP算是OOP的一种补充、一种分支,还是一种超越?”

叹号故作捶胸顿足状:“OOP还没有完全吃透,又来了个什么AOP。”

“不同的人对新生事物采取不同的态度。”冒号王顾左右而言他,“追星族倾向于盲目追捧,唯恐落伍,他们信奉新潮的、流行的就是好的;守旧派倾向于本能抗拒,回避求新,他们认为经典的、传统的才是好的。”

引号和叹号互视一眼,不情愿地戴上了老冒派发的帽子。

冒号续道:“从宏观角度看,太阳底下没有新鲜事AOP无非是SoC原理和DRY原则的一种应用;从微观角度看,太阳每天都是新的AOP虽自OOP的土壤中长出,却脱离藩篱自成一体,并且嫁接到非OOP的领地,不仅在纯过程式语言、函数式语言,甚至逻辑式语言中得到发展,而且本身也具备了一定的声明式语言特征,成为一种新的软件模块化方式。”

问号举手:“什么是SoCDRY?”

引号代答:“SoC就是Separation of Concerns,即关注点分离;DRYDon’t Repeat Yourself,即尽量减少重复代码。”

“答案正确,加十分!”冒号戏赞道,“不良代码通常有两种病征:一是结构混乱,或聚至纠缠打结、或散至七零八落;二是代码重复,叠床架屋、臃肿不堪。治疗此类病症一个有效的方法是抽象与分解:从问题中抽象出一些关注点,再以此为基础进行分解。分解后的子问题主题鲜明且独立完备,既不会牵一发而动全身,也不会四分五裂、支离破碎。同时具有相同特征的部分可以像代数中的公因子一样提取出来,提高了重用性,减少了重复性。”

句号醒悟道:“这不就是模块化吗?”

“准确地说,抽象是前提,分解是方式,模块化是结果。”冒号很讲究精确,“大家记得庖丁解牛的故事吧?在常人眼中复杂的牛体,庖丁经过抽象,已目无全牛,及至提刀分解,自是游刃有余。待牛如土委地,模块化即成。”

句号举一反三:“前面提到的编程范式的基本思想大多不也如此?将程序分别抽象分解为过程、函数、断言、对象和进程,就依次成为过程式、函数式、逻辑式、对象式和并发式。至于泛型式—”

句号讲不下去了。

“泛型式虽未引入新类型的模块,其核心也是抽象出算法后与数据分解。”冒号为其解围,“以此类推,切面式的AOP将程序抽象分解为切面。”

问号提问:“抽象与分解的原则是什么?”

冒号作了个V字:“两条:单一化,正交化。每个模块职责明确专一,模块之间相互独立,即高内聚低耦合high cohesion & low coupling[1]。此原则相当普适,是分析复杂事物的一种基本方法,在数学和物理中应用得尤为广泛,如质因式分解、正交分解、谱分解,等等。”

逗号调皮地抬杠:“为什么称为正交化呢?斜交化不行吗?”

冒号呵呵一笑:“在数学中互为正交的两个向量在彼此方向上投影为零,意味着彼此独立、互不影响,斜交可不行。”

逗号吐了吐舌头。

“诚如前述,AOP以切面为模块。”冒号返回主题,“切面Aspect常直译为‘方面’,但它描述的是横切关注点(cross-cutting concerns),故‘切面’更准确生动,而‘方面’则失之空泛呆板。何谓横切关注点?顾名思义,乃是与程序的纵向主流执行方向横向正交的关注焦点。不妨回顾一下,无论是过程式的函数,还是对象式的方法,都包含了完整的执行代码。但有些代码横跨多个模块,以片断的形式散落在各处,虽具有相似的逻辑,却无法用传统的方式提炼成模块,难以实现SoCDRY。典型的例子如:在调用某些对象的方法、读写某些对象的域、抛出某些异常等前后需要用到统一的业务逻辑,诸如日志输出、代码跟踪、性能监控、异常处理、安全检查、事务管理,等等。为解决此类问题,AOP应运而生。它将每类横切关注点封装到单独的Aspect模块中,将程序中的一些执行点与相应的代码绑定起来。单个的执行点称为接入点(join point)。例如,调用某个对象的方法前后;符合预先指定条件的接入点集合称为切入点(pointcut)。再如,所有以set为命名开头的方法;每段绑定的代码称为一个建议(advice)。”

问号有点疑问:“接入点与切入点有何区别?”

冒号释疑:“望文生义,接入处是点,切入处是面,面由点组成。advice定义于切入点上,执行于接入点处。换言之,共享一段附加代码的接入点组成了一个切入点。切入点一般用条件表达式来描述,不仅有广泛性,还有预见性—以后新增的代码如果含有满足切入点条件的接入点,advice中的代码便自动附着其上。这是AOP威力所在,但有时也是麻烦所在。”

引号很较真:“好像一些书上把join point译作连接点,把advice译作通知。”

“误导,完全是误导!”冒号有些痛心疾首,“何谓join point?是advice中额外代码接入之处,join显为‘参加’、‘加入’之意。如果说翻作‘连接’ 只是因缺乏动感和方向性而不够贴切的话,将advice译作‘通知’则近乎荒谬了。advice是在原有程序流程中加入的额外流程,可理解为建议采取的措施,而‘通知’强调的是一种信息,难道是程序运行到join point的信息?抑或采取某种行动的信息?简直不知所云。”

顿了一会,冒号仍意犹未尽:“英文好的技术不好,技术好的英文不好,两者都好的不屑去翻译,导致市面上的译书虽汗牛充栋,然佳作寥寥。这里奉劝各位,如果真想成为优秀的程序员,一定要尽可能地读原文的书籍、文章和文档。事实上,凡是科学和艺术方面的专业人员,要想专业水平上一层台阶,都应读该专业权威经典原文。要知道,语言之间的天堑原本难以弥合,译者的专业水准、语言功底和严谨程度更是参差不齐。纵使万事俱备,一年半载后的译书便如隔夜的饭菜,虽刚出炉,已然不新鲜了。”

逗号抱怨:“英文虽读得懂,但太慢、太费劲了。”

“多读,读多了就习惯了。”冒号鼓励着,“对程序员来说,英语也是一门计算机语言,而且是必修的语言。”

课堂上有这么一个规律,越是题外的话大家讨论得越欢。下面果然开始嘈杂起来,冒号也乐得乘机歇歇嘴。

等大伙渐渐把视线重新聚焦到讲台上,冒号才继续讲课:“从软件重用的角度看,可以这么理解AOPOOP的关系:OOP只能沿着继承树的纵向方向重用,而AOP则弥补了OOP的不足,可以在横向方向重用。这算是回答了引号开始提出的问题:AOP不是OOP的分支,也不能说是超越了OOP,而是OOP的一种补充—尽管AOP并不局限于OOP语言。”

问号的求知欲很强:“AOP实现的机理是什么?”

冒号回答:“如果一个程序是一个管道系统,AOP就是在管道上钻一些孔,在每个孔中注入新的代码流。因此AOP实现的关键是将advice的代码嵌入到主体程序之中,术语称编织(weaving)。这是很自然的—将问题分解之后再合成,问题才得以还原。编织可分两种:一种是静态编织,通过修改源码或字节码(bytecode)在编译期compile-time)、后编译期post-compile)或加载期load-time)嵌入代码—请注意,这里涉及刚才提到的元编程和产生式编程;另一种是动态编织,通过代理(proxy)等技术在运行期run-time)实现嵌入。具体的工具包括一些扩展性语言如AspectJAspectC++Aspect#等和一些框架如AspectWerkzSpringJboss AOP等。”

叹号搔着头:“听起来怪复杂的。”

引号倒不在乎:“这些机理是AOP的实现者需要操心的,使用者只需关心AOP是否好用,性能如何,等等。”

“为了让你们有更直观的印象,我们借用光学原理来类比。”冒号用幻灯片展示(如图3-3所示)

3-3  切面式编程

“众所周知,白光经过三棱镜的折射而分解为七色光,是谓光的色散。再经过一个倒置的三棱镜,七色光又重新会聚为白光。”冒号简述中学的物理知识,“如果把一个复杂的系统看作复合色的白光,经过第1个三棱镜—关注分离器,系统被分解为不同的切面,如同不同的单色的彩光。这些切面经过第2个三棱镜—编织器,再度合成为原系统。”

叹号脸上的迷惘之色渐去:“这下清楚多了。”

句号积极发言:“从中看出,AOP的实施分3步:切面分解、切面实现和切面合成。其中第1步是在设计者的头脑中进行的,第3步是通过AOP的工具实现的,真正须要程序员编码的部分在第2步,即分别实现各切面的advice。”

冒号赶紧补漏:“你好像忽略了切面的另一要素pointcut,如果程序员不指明advice挂靠的切入点,系统如何知道该何时何处调用他编写的执行代码呢?”

句号的嘴张成O状:“是哦,我怎么把这茬给忘了?”

AOP的议题结束前,冒号不忘指出:“与OOP一样,AOP在带来便利的同时,也增加了一定的复杂度和性能损耗。它们更适用于大中型程序,用在小型程序中则不啻牛刀杀鸡。”

总结

SoCSeparation of concerns的缩写,指应将关注点分离;DRYDon’t Repeat Yourself的缩写,指应尽量减少重复代码。

抽象与分解是治愈代码紊乱、松散、重复的良方。

抽象与分解的原则是单一化和正交化,以保障软件系统符合“高内聚、低耦合”的要求。

横切关注点指与程序的纵向主流执行方向横向正交的关注焦点

接入点是附加行为—建议(advice)的执行点,切入点(pointcut)是指定的接入点(join point)集合,这些接入点共享一段插入代码。切入点与建议组成了切面(aspect),是模块化的横切关注点。

编织是将附加的切面逻辑嵌入到主体应用程序之中的过程。编织分静态编织和动态编织两种。静态编织在编译期、后编译期或加载期嵌入代码,动态编织则在运行期嵌入。

AOP的实施分3步:切面分解、切面实现和切面合成。

OOP只能沿继承树的纵向方向重用,AOP可以沿横向方向重用。

语言之间的天然差别、译者的专业水准、语言功底和严谨程度及时间上的滞后决定了阅读原文书籍和资料的必要性。

参考

[1]   WikipediaAspect-oriented programming
http://en.wikipedia.org/wiki/Aspect-oriented_programming

[2]   Ramnivas Laddad I want my AOP!
http://www.javaworld.com/javaworld/jw-01-2002/jw-0118-aspect.html

插语

[1]耦合(coupling)用来衡量模块之间的依赖程度,内聚(cohesion)用来衡量模块内在的关联强度。它们常用来作为软件质量的评判标准,耦合度宜低,内聚度宜高。

欢迎转载,转载时请注明:

本文出自电子工业出版社博文视点(武汉)新书《冒号课堂——编程范式与OOP思想》。

http://www.china-pub.com/196068&ref=ps

http://www.douban.com/subject/4031906/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
智慧农业是一种结合了现代信息技术,包括物联网、大数据、云计算等,对农业生产过程进行智能化管理和监控的新模式。它通过各种传感器和设备采集农业生产中的关键数据,如大气、土壤和水质参数,以及生物生长状态等,实现远程诊断和精准调控。智慧农业的核心价值在于提高农业生产效率,保障食品安全,实现资源的可持续利用,并为农业产业的转型升级提供支持。 智慧农业的实现依赖于多个子系统,包括但不限于设施蔬菜精细化种植管理系统、农业技术资料库、数据采集系统、防伪防串货系统、食品安全与质量追溯系统、应急追溯系统、灾情疫情防控系统、农业工作管理系统、远程诊断系统、监控中心、环境监测系统、智能环境控制系统等。这些系统共同构成了一个综合的信息管理和服务平台,使得农业生产者能够基于数据做出更加科学的决策。 数据采集是智慧农业的基础。通过手工录入、传感器自动采集、移动端录入、条码/RFID扫描录入、拍照录入以及GPS和遥感技术等多种方式,智慧农业系统能够全面收集农业生产过程中的各种数据。这些数据不仅包括环境参数,还涵盖了生长状态、加工保存、检验检疫等环节,为农业生产提供了全面的数据支持。 智慧农业的应用前景广阔,它不仅能够提升农业生产的管理水平,还能够通过各种应用系统,如库房管理、无公害监控、物资管理、成本控制等,为农业生产者提供全面的服务。此外,智慧农业还能够支持政府监管,通过发病报告、投入品报告、死亡报告等,加强农业产品的安全管理和质量控制。 面对智慧农业的建设和发展,存在一些挑战,如投资成本高、生产过程标准化难度大、数据采集和监测的技术难题等。为了克服这些挑战,需要政府、企业和相关机构的共同努力,通过政策支持、技术创新和教育培训等手段,推动智慧农业的健康发展。智慧农业的建设需要明确建设目的,选择合适的系统模块,并制定合理的设备布署方案,以实现农业生产的智能化、精准化和高效化。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值