廖躍鈞
摘 要:目前傳統(tǒng)的程序設(shè)計(jì)——面向?qū)ο缶幊蹋∣bject-Oriented Programming,OOP)已經(jīng)成為業(yè)界的主流,是大多數(shù)軟件項(xiàng)目開發(fā)的首選技術(shù)。當(dāng)用OOP對(duì)公共行為進(jìn)行建模時(shí),它展示出強(qiáng)大的功能,但它在解決橫跨多個(gè)模塊的行為時(shí),如在處理一些關(guān)注點(diǎn)分散問(wèn)題存在著一定的局限性,甚至?xí)拐麄€(gè)項(xiàng)目開發(fā)出現(xiàn)混亂不清的局面。在這里將共同探討面向方面編程技術(shù)(AOP)的思想,基本概念和原理,并通過(guò)具體的例子簡(jiǎn)單介紹了面向方面編程技術(shù)(AOP)在信息系統(tǒng)中的研究與實(shí)踐。
關(guān)鍵詞:面向方面編程 信息系統(tǒng) 程序設(shè)計(jì)
中圖分類號(hào):TP31 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1672-3791(2015)08(c)-0006-04
Research and Practice of Information System Based on Aspect-oriented Programming (AOP) Technology
Liao Yuejun
(Guangdong Medical College,Dongguan,Guangdong Province, 523808 China)
Abstract:The traditional Programming,Object Oriented Programming(Object-oriented Programming,OOP) has become the mainstream of the industry,is the first choice for most software project development technology.When using OOP to public behavior modeling,it shows powerful features,but it in solving behavior across multiple modules,such as in dealing with some scattered focus there is certain limitation,even can cause a confusion of the whole project development situation.Here we discuss the thought of aspect-oriented programming(AOP)technology,the basic concept and principle,and through the concrete example simple aspect-oriented programming(AOP)technology is introduced in the research and practice of information system.
Key Words:Aspect-Oriented Programming;Information system;Program design
從上世紀(jì)九十年代至今,Object-Oriented Programming(OOP)都是主流的程序編程設(shè)計(jì)方式。面向?qū)ο蠹夹g(shù)思想的出現(xiàn)改變了大家程序設(shè)計(jì)的思路,大大地提高了軟件生產(chǎn)效率。并且面向?qū)ο蠹夹g(shù)符合大家對(duì)事物認(rèn)識(shí)的思維習(xí)慣,它早已被證明是一種行之有效的軟件開發(fā)方法。面向?qū)ο缶幊碳夹g(shù)思想是將世界上的萬(wàn)事萬(wàn)物都視為對(duì)象,在編程世界里將所有的數(shù)據(jù)和對(duì)數(shù)據(jù)的操作聯(lián)系在一起,把他們當(dāng)作捆綁在一起的整體——對(duì)象。然后再把那些有共同屬性和行為的對(duì)象,進(jìn)行歸類,對(duì)于同一類的對(duì)象經(jīng)過(guò)抽象后,稱之為類,因此類就是描述相同類型的對(duì)象集合,定義好類后,我們又通過(guò)類來(lái)產(chǎn)生有著共同數(shù)據(jù)屬性和相同行為的新對(duì)象,故對(duì)象是無(wú)窮無(wú)盡的,一切事物皆對(duì)象。面向?qū)ο缶幊叹褪嵌x各組相同類型對(duì)象的集合——類,再由類來(lái)生成對(duì)象,對(duì)象和對(duì)象之間再進(jìn)行通信。這就是面向?qū)ο缶幊痰募夹g(shù)思想,盡管利用面向?qū)ο缶幊痰募夹g(shù)思想,可以建立對(duì)象模型與現(xiàn)實(shí)世界的系統(tǒng)模型的匹配,但是在實(shí)際的軟件項(xiàng)目中,卻仍然存在一些對(duì)象方法很難解決的問(wèn)題。如在解決橫跨多個(gè)模塊的行為時(shí),如在處理一些關(guān)注點(diǎn)分散問(wèn)題存在著一定的局限性甚至?xí)拐麄€(gè)項(xiàng)目開發(fā)出現(xiàn)混亂不清的局面。AOP已被證實(shí)是一種有效地簡(jiǎn)化軟件系統(tǒng)復(fù)雜度的方法。它的主要思想來(lái)源于軟件設(shè)計(jì)中關(guān)注點(diǎn)的分離。
1 AOP的基本原理
1.1 概念
由于AOP的應(yīng)用程序結(jié)構(gòu)與傳統(tǒng)高級(jí)語(yǔ)言的應(yīng)用程序結(jié)構(gòu)基本類似,傳統(tǒng)的高級(jí)語(yǔ)言系統(tǒng)實(shí)現(xiàn)由以下三部分組成:編程語(yǔ)言;編譯器;項(xiàng)目開發(fā)的應(yīng)用程序,故AOP的系統(tǒng)實(shí)現(xiàn)也有以上三個(gè)相應(yīng)部分:語(yǔ)言;聯(lián)結(jié)器,核心級(jí)模塊。所謂的面向切面編程(AOP)其實(shí)是對(duì)業(yè)務(wù)邏輯又進(jìn)行了進(jìn)一步的抽取,將多種業(yè)務(wù)邏輯中的公用部分抽取出來(lái)做成一種服務(wù)(比如日志記錄,性能統(tǒng)計(jì),安全驗(yàn)證等),從而實(shí)現(xiàn)程序代碼的重用。另外這種服務(wù)通過(guò)配置,可以動(dòng)態(tài)的給程序添加統(tǒng)一控制,利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行分離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低。那么要進(jìn)一步了解AOP的的基本原理,首先要弄清楚這幾個(gè)概念具體指的是什么。
(1)Aspect(方面):對(duì)橫切關(guān)注點(diǎn)的模塊化,通知和切入點(diǎn)的組合被稱之為方面,故方面是用來(lái)定義一段程序中所包括的邏輯,以及安排何時(shí)執(zhí)行這個(gè)邏輯。
(2)Advice(通知):在某一個(gè)特定的聯(lián)結(jié)點(diǎn)處運(yùn)行的代碼稱為“通知”,是要切入的邏輯,對(duì)橫切關(guān)注點(diǎn)的具體實(shí)現(xiàn),有分類的概念。通知有很多種,比如在Before Advice 在方法前切入;After Advice 在方法后切入;拋出異常時(shí)也會(huì)切入:After Returning Advice 在方法返回后切入,拋出異常則不會(huì)切入;After Throwing Advice 在方法拋出異常時(shí)切入。Around Advice 在方法執(zhí)行前后切入,可以中斷或忽略原有流程的執(zhí)行
(3)Pointcut(切入點(diǎn)) :一個(gè)切入點(diǎn)是用來(lái)定義某一個(gè)通知該何時(shí)執(zhí)行的一組聯(lián)結(jié)點(diǎn),定義了Advice(通知)應(yīng)用到哪些JoinPoint(聯(lián)結(jié)點(diǎn))上,對(duì)Spring來(lái)說(shuō)就是函數(shù)調(diào)用。Joinpoint的表達(dá)式,表示攔截哪些方法。一個(gè)Pointcut對(duì)應(yīng)多個(gè)Joinpoint。
(4)JointPoint(連接點(diǎn)):一個(gè)程序執(zhí)行過(guò)程中的連接點(diǎn),如某個(gè)業(yè)務(wù)方法,。典型的攔截點(diǎn)就是調(diào)用一個(gè)函數(shù);它用來(lái)定義在程序的哪里通過(guò)AOP加入新的邏輯。
(5)Target Object Advice(被應(yīng)用的目標(biāo)對(duì)象):如果一個(gè)對(duì)象的執(zhí)行過(guò)程受到某一個(gè)AOP的應(yīng)用,那么它就叫一個(gè)被應(yīng)用的目標(biāo)對(duì)象。目標(biāo)對(duì)象通常也稱為被通知對(duì)象。
(6)Weaving(織入):織入是將方面真正加入程序代碼的過(guò)程。
(7)Introduction(引入):可以動(dòng)態(tài)的為類添加新的方法或?qū)傩浴?/p>
他們之間的關(guān)系如圖1所示。
1.2 AOP程序的設(shè)計(jì)步驟
AOP應(yīng)用程序包括以下三個(gè)明顯的開發(fā)步驟:
(1)將系統(tǒng)需求進(jìn)行功能性分解,區(qū)分出核心關(guān)注點(diǎn)以及橫切關(guān)注點(diǎn);
(2)單獨(dú)完成每一個(gè)關(guān)注點(diǎn)的編碼和實(shí)現(xiàn),構(gòu)造核心級(jí)模塊以及Aspect系統(tǒng)級(jí)模塊;
(3)用聯(lián)結(jié)器指定的重組規(guī)則,將核心級(jí)模塊和aspect系統(tǒng)級(jí)模塊進(jìn)行組合,形成最終系統(tǒng)。
2 AOP在信息系統(tǒng)中的實(shí)踐
為了建立松散耦合的、可擴(kuò)展的信息系統(tǒng),AOP應(yīng)用到的橫切技術(shù),通常分為兩種類型:動(dòng)態(tài)橫切和靜態(tài)橫切。動(dòng)態(tài)橫切就是通過(guò)切入點(diǎn)和連接點(diǎn)在一個(gè)方面中創(chuàng)建行為的過(guò)程,連接點(diǎn)可以在執(zhí)行時(shí)橫向地應(yīng)用于現(xiàn)有對(duì)象。動(dòng)態(tài)橫切通常用于幫助向?qū)ο髮哟沃械母鞣N方法添加日志記錄或身份認(rèn)證。在很多應(yīng)用場(chǎng)景中,動(dòng)態(tài)橫切技術(shù)基本上代表了AOP。動(dòng)態(tài)橫切技術(shù)的核心主要包括jointpoint(連接點(diǎn)),pointcut(切入點(diǎn)),advice(通知)和aspect(方面)。在前面,已經(jīng)概要地介紹了這些術(shù)語(yǔ)分別代表的含義。接下來(lái),將以一個(gè)具體的實(shí)例來(lái)進(jìn)一步闡述它們?cè)贏OP動(dòng)態(tài)橫切在實(shí)際信息系統(tǒng)中的作用。以一個(gè)學(xué)生考試系統(tǒng)為例子,考慮到學(xué)生考試系統(tǒng)的功能,就是需要對(duì)試題進(jìn)行添加、刪除、修改等管理操作。也就是說(shuō),在實(shí)際的應(yīng)用場(chǎng)景中,這些行為因?yàn)樯婕暗綌?shù)據(jù)庫(kù)的增、刪、改操作,所以必須添加事務(wù)才能使操作成功。首先采用傳統(tǒng)的OOP程序設(shè)計(jì)方法,其偽代碼如下:
public class QuestionManager {
privateQuestionDaoquestionDao;
public void addQuestion(QuestionDtoquestionDto) {
Transaction t = new Transaction();
questionDao.insert(questionDto);
t.commit();
}
public void deleteQuestion(QuestionDtoquestionDto) {
Transaction t = new Transaction();
questionDao.delete(questionDto);
t.commit();
}
public void updateQuestion(QuestionDtoquestionDto){
Transaction t = new Transaction();
questionDao.update(questionDto);
t.commit();
}
}
同樣的,在該考試系統(tǒng)中,還需要對(duì)試卷進(jìn)行管理,它采用了同樣的事務(wù)機(jī)制:
public class PaperManager {
privatePaperDaopaperDao;
public void addPaper(PaperDtopaperDto) {
Transaction t = new Transaction();
paperDao.insert(paperDto);
t.commit();
}
public void deletePaper(PaperDtopaperDto) {
Transaction t = new Transaction();
paperDao.delete(paperDto);
t.commit();
}
public void updatePaper(PaperDtopaperDto){
Transaction t = new Transaction();
paperDao.update(paperDto);
t.commit();
}
}
如此以來(lái),在整個(gè)學(xué)生考試系統(tǒng)中,核心業(yè)務(wù)包括試題管理和試卷管理,它們都需要相同的事務(wù)管理,如圖2所示:
也就是說(shuō),利用AOP技術(shù),可以分離出系統(tǒng)的核心關(guān)注點(diǎn)和橫切關(guān)注點(diǎn),從橫向的角度,截取業(yè)務(wù)管理行為的內(nèi)部消息,以達(dá)到織入事務(wù)管理邏輯的目的。當(dāng)執(zhí)行addQuestion()等方法時(shí),系統(tǒng)將添加事務(wù)完成添加試題功能,調(diào)用橫切關(guān)注點(diǎn)邏輯,因此該方法即為AOP的join point。對(duì)于學(xué)生考試系統(tǒng)而言,每個(gè)需要事務(wù)的方法都是一個(gè)單獨(dú)的join point。由于事務(wù)管理將在每個(gè)方法執(zhí)行前執(zhí)行,所以對(duì)于這一系列join point,只需要定義一個(gè)point cut。當(dāng)系統(tǒng)執(zhí)行到j(luò)oin point處時(shí),將根據(jù)定義去查找對(duì)應(yīng)的point cut,然后執(zhí)行這個(gè)橫切關(guān)注點(diǎn)需要實(shí)現(xiàn)的邏輯,即advice。而point cut和advice,就組合成了一個(gè)事務(wù)管理的aspect方面。
由于aspect是一個(gè)封裝的對(duì)象,可以定義這樣一個(gè)aspect:
private static aspect TransactionAspect{……}然后在這個(gè)aspect中定義point cut,在point cut中,定義了需要截取上下文消息的方法,例如:
privatepointcutTransactionExecution();
execution(public void QuestionManager.addQuestion(QuestionDto)) ||
execution(public void QuestionManager.deleteQuestion(QuestionDto)) ||
execution(public void QuestionManager.updateQuestion(QuestionDto)) ||
execution(public void PaperManager.addPaper(PaperDto)) ||
execution(public void PaperManager.deletePaper(PaperDto))||
execution(public void PaperManager.updatePaper(PaperDto));
由于事務(wù)管理是在試題管理方法執(zhí)行之前完成,因此在before advice中,定義事務(wù)管理:
before(): transactionExecution()
{
Transaction t = new Transaction();
questionDao.insert(questionDto);
t.commit();
}
通過(guò)定義了這樣一個(gè)完整的aspect,當(dāng)系統(tǒng)調(diào)用QuestionManager或PaperManager的相關(guān)方法時(shí),就觸發(fā)了point cut,然后調(diào)用相應(yīng)的advice邏輯。如此以來(lái),QuestionManager和PaperManager模塊就與事務(wù)管理模塊完全解除了依賴關(guān)系,同時(shí)也消除了傳統(tǒng)設(shè)計(jì)中不可避免的事務(wù)處理的重復(fù)代碼。這對(duì)于建立一個(gè)松散耦合、可擴(kuò)展的系統(tǒng)軟件是非常有利的,同時(shí)提高了軟件開發(fā)速度。
4 AOP存在的問(wèn)題
大家知道AOP的橫切關(guān)注點(diǎn)是跨越多個(gè)模塊的,但目前在技術(shù)上通常只能采用一維方法學(xué)來(lái)實(shí)現(xiàn),這使得從需求到實(shí)現(xiàn)只能沿著單一的維來(lái)映射。這個(gè)單一的維通常是核心模塊級(jí)實(shí)現(xiàn),其它需求則與其相互交織在一起。即需求空間是多維空間,而實(shí)現(xiàn)空間卻是一維空間,這樣的不匹配造成了從需求到實(shí)現(xiàn)的不統(tǒng)一。
采用目前的方法學(xué)來(lái)實(shí)現(xiàn)橫切關(guān)注點(diǎn)已證實(shí)存在許多問(wèn)題,主要有:
*代碼交織(code tangling):一個(gè)軟件系統(tǒng)的模塊可能同時(shí)與數(shù)個(gè)需求交互;
*代碼分散(code scattering):由于橫切關(guān)注點(diǎn)跨越多個(gè)模塊,所以與這些橫切關(guān)注點(diǎn)相關(guān)的實(shí)現(xiàn)代碼也跨越多個(gè)模塊;
*代碼重用性差:由于一個(gè)模塊中包含對(duì)多個(gè)關(guān)注點(diǎn)的實(shí)現(xiàn),使得對(duì)類似功能有需求的其它系統(tǒng)不能很方便地重用該模塊;
難以維護(hù)和升級(jí):由于系統(tǒng)橫切關(guān)注點(diǎn)的模塊性差,如果系統(tǒng)需要改動(dòng)一個(gè)功能,則需要修改多個(gè)相應(yīng)的模塊才能實(shí)現(xiàn),這樣極易造成系統(tǒng)的不一致,而且還需進(jìn)行大量的測(cè)試工作以確保不會(huì)引起新的Bug。
5 結(jié)語(yǔ)
AOP技術(shù)自從1997年正式提出以來(lái),經(jīng)過(guò)多年的發(fā)展,已取得很大的成效。目前支持面向方面編程的語(yǔ)言已有許多種,如AspectJ、AspectC、AspectC++、JBoss、Spring等。其中以AspectJ語(yǔ)言最為成熟,很多實(shí)際的工程項(xiàng)目已用該語(yǔ)言解決了大量像日志、安全、事務(wù)、策略等橫切關(guān)注點(diǎn)問(wèn)題。AOP語(yǔ)言的使用解除了OOP語(yǔ)言代碼混亂、交織的局面,最大程度上實(shí)現(xiàn)了代碼的重用,方便了軟件項(xiàng)目的升級(jí)與維護(hù)。
參考文獻(xiàn)
[1] 薛冰.改進(jìn)AOP技術(shù)在軟件開發(fā)中的應(yīng)用與研究[D].大連:大連交通大學(xué),2013.
[2] 王書懷,邢建春,李決龍,等.AOP技術(shù)在信息管理系統(tǒng)中的應(yīng)用研究[J].計(jì)算機(jī)應(yīng)用與軟件,2012,29(6):189-195.
[3] 劉余和.面向Aspect技術(shù)在海關(guān)EAI中的實(shí)踐與研究[D].廣州:中山大學(xué),2006.
[4] G Kiczales, J Lamping, A Mendhekar, et al. Aspect-Oriented Programming [C].In European Conference on Object-oriented Program,1997,44(2):217-235.