面向方面的程序設(shè)計_第1頁
面向方面的程序設(shè)計_第2頁
面向方面的程序設(shè)計_第3頁
面向方面的程序設(shè)計_第4頁
面向方面的程序設(shè)計_第5頁
已閱讀5頁,還剩51頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1面向方面的程序設(shè)計--

兼談計算科學(xué)的創(chuàng)新2面向方面的程序設(shè)計Aspectorientedprogramming(AOP)3Xerox(施樂)公司PARC研究中心在1997年的歐洲面向?qū)ο缶幊檀髸‥COOP97)上首次提出Aspect-orientedprogramming(AOP)。自2002年起,每年分別在歐洲和美國輪流召開專門的面向方面軟件開發(fā)(AOSD)國際會議。與會者包括美國、加拿大、荷蘭、英國、法國、丹麥、日本、以色列等。我國一些學(xué)校也對AOP給以關(guān)注并開展了一些研究工作。從AOP概念提出經(jīng)過了近十年的時間,這種技術(shù)現(xiàn)在已經(jīng)開始被工業(yè)界采用。

4AOP產(chǎn)生的背景

計算機(jī)軟件設(shè)計的一個重要原則,就是要清晰分離各種關(guān)注點(diǎn)(separationofconcerns),然后分而治之,各個擊破,最后形成統(tǒng)一的解決方案。業(yè)務(wù)邏輯存儲日志安全需求關(guān)注點(diǎn)標(biāo)識5

關(guān)注點(diǎn):是指一個特定的目標(biāo)、概念或者興趣域。從技術(shù)的角度,軟件系統(tǒng)分別包括核心級和系統(tǒng)級的關(guān)注點(diǎn)。核心級關(guān)注點(diǎn)是系統(tǒng)要完成的業(yè)務(wù)功能;系統(tǒng)級關(guān)注點(diǎn)是完成核心級關(guān)注點(diǎn)所必須的配套設(shè)施,這些配套設(shè)施通常被認(rèn)為是整個系統(tǒng)的系統(tǒng)特性,或者是業(yè)務(wù)功能的功能約束。例如:信用卡處理系統(tǒng)核心關(guān)注點(diǎn)是處理付款;系統(tǒng)級關(guān)注點(diǎn)包括日志、事務(wù)、認(rèn)證、安全和性能等等。6軟件系統(tǒng)中,某個行為,例如操作日志的記錄,存在于軟件的各個部分中,這個行為可以看作是橫向存在于軟件之中,他所關(guān)注的是軟件的各個部分的一些共有的行為。在很多情況下,這種行為不屬于業(yè)務(wù)邏輯的一部分。這種操作并不是業(yè)務(wù)邏輯調(diào)用的必須部分,但是,我們卻往往不得在代碼中顯式進(jìn)行調(diào)用,并承擔(dān)由此帶來的后果。7在目前的技術(shù)框架下,通常系統(tǒng)級關(guān)注點(diǎn)在邏輯上相互之間彼此正交(相互獨(dú)立),同時在實(shí)現(xiàn)上趨向于和若干核心模塊交織。例如:信用卡管理系統(tǒng)的每個核心業(yè)務(wù)關(guān)注點(diǎn)都和安全、日志等系統(tǒng)關(guān)注點(diǎn)相聯(lián)系。8核心級關(guān)注點(diǎn)(業(yè)務(wù))多數(shù)情況下可以被很好地分解,并通過編程語言模塊化實(shí)現(xiàn)(子模塊或軟構(gòu)件)。系統(tǒng)級關(guān)注點(diǎn)(橫向關(guān)注點(diǎn)),使用當(dāng)前的程序設(shè)計方法導(dǎo)致在許多構(gòu)件中要重復(fù)包含(擴(kuò)散)這些代碼。9橫切示例(crosscutting)Authentication權(quán)限Caching緩存Contextpassing內(nèi)容傳遞Errorhandling錯誤處理Lazyloading懶加載Debugging調(diào)試Logging、tracing、profilingandmonitoring日志、跟蹤、優(yōu)化、校準(zhǔn)Performanceoptimization性能優(yōu)化Persistence持久化Resourcepooling資源池Synchronization同步Transactions事務(wù)10現(xiàn)有軟件技術(shù)的不足

目前的實(shí)現(xiàn)技術(shù)只提供了一維方法學(xué)實(shí)現(xiàn)系統(tǒng)的關(guān)注點(diǎn),該單一維度一般是核心需求和關(guān)注點(diǎn)的模塊化實(shí)現(xiàn),其他類型的需求也被迫和該主導(dǎo)維度一致。安全事務(wù)業(yè)務(wù)業(yè)務(wù)主導(dǎo)維

問題空間是n維的,而解空間是一維的。這種失配必然導(dǎo)致需求和實(shí)現(xiàn)之間的失配。11源程序就會變成一些為不同關(guān)注目的而編制的指令的纏結(jié)混亂物。纏結(jié)現(xiàn)象是現(xiàn)有軟件系統(tǒng)中許多不必要的復(fù)雜性的核心。它增加了功能構(gòu)件之間的依賴性,分散了構(gòu)件原來假定要做的事情,提供了許多程序設(shè)計出錯的機(jī)會,使得一些功能構(gòu)件難以復(fù)用,源代碼難以開發(fā)、理解和發(fā)展。12某一應(yīng)用的領(lǐng)域?qū)<?,不太可能對分布、認(rèn)證、訪問控制、同步、加密、冗余等問題的復(fù)雜實(shí)現(xiàn)機(jī)制很熟悉,所以就不能保證他們在程序中進(jìn)行正確的調(diào)用。開發(fā)人員很難正確預(yù)見到未來對程序的新需求。13方面(Aspect)設(shè)計上講,是橫切系統(tǒng)的一些軟件系統(tǒng)級關(guān)注點(diǎn)。實(shí)現(xiàn)上講,它支持將橫切系統(tǒng)的關(guān)注點(diǎn)封裝在單獨(dú)的模塊單位中,它是AOP將橫切關(guān)注點(diǎn)局部化和模塊化的實(shí)現(xiàn)機(jī)制。常見的“方面”: 異常和出錯處理 同步和并發(fā)控制 內(nèi)存訪問模式 日志、安全 事務(wù)、性能 14AOP核心內(nèi)容就是所謂的“橫切關(guān)注點(diǎn)”,即“方面”,Aspect是AOP提供的一種程序設(shè)計單元。而在OOP中,這些一般關(guān)注點(diǎn)的實(shí)現(xiàn)單元叫作類

AOP的目標(biāo),是要將這些橫切關(guān)注點(diǎn)與業(yè)務(wù)邏輯代碼相分離,從而得到更好的軟件結(jié)構(gòu)、性能以及穩(wěn)定性等方面的好處。

AOP被認(rèn)為是后面向?qū)ο髸r代的一種新的重要的程序設(shè)計技術(shù)。15AOP的基本思想通過分別描述系統(tǒng)的不同關(guān)注點(diǎn)及其關(guān)系,以一種松耦合的方式實(shí)現(xiàn)單個關(guān)注點(diǎn),然后依靠AOP環(huán)境的支撐機(jī)制,將這些關(guān)注點(diǎn)組織或編排成最終的可運(yùn)行程序。普通關(guān)注點(diǎn)可以使用傳統(tǒng)的結(jié)構(gòu)化方法和面向?qū)ο蠓椒w統(tǒng)的機(jī)制。系統(tǒng)關(guān)注點(diǎn)使用Aspect機(jī)制。16AOP程序設(shè)計的一般步驟一、對需求規(guī)約進(jìn)行Aspect分解。確定哪些功能是組件必須實(shí)現(xiàn)的,即提取出核心關(guān)注點(diǎn)。哪些功能可以以aspect的形式動態(tài)加入到系統(tǒng)組件中去,即提取出系統(tǒng)級的橫切關(guān)注點(diǎn)。17AOP程序設(shè)計的一般步驟二、對標(biāo)識出的Aspect分別通過程序機(jī)制實(shí)現(xiàn)。構(gòu)造系統(tǒng)的組件。利用組件語言實(shí)現(xiàn)系統(tǒng)的組件。對于OOP語言,這些組件可以是類;對于過程化程序設(shè)計語言,這些組件可以是各種函數(shù)和API。構(gòu)造系統(tǒng)的aspect。利用一種或多種aspect語言實(shí)現(xiàn)aspect。

aspect語言必須提供聲明aspect的機(jī)制。aspect如何聲明連接點(diǎn)如何定義aspect代碼如何定義aspect的參數(shù)化程度等18三、用aspect編織器將所有的單元編排重組在一起,形成最終的可運(yùn)行系統(tǒng)。為組件語言和aspect語言構(gòu)造相應(yīng)的語法樹;依據(jù)aspect中的連接點(diǎn)定義對語法樹進(jìn)行聯(lián)結(jié);在連接的語法樹上生成中間文件或目標(biāo)代碼。

aspect語言必須提供將aspect代碼和基礎(chǔ)代碼組合編排(weaving)在一起的機(jī)制。定義編排語言和規(guī)則。解決aspect之間潛在的沖突。為組裝和執(zhí)行建立外部約束。aspect語言必須提供生成可運(yùn)行系統(tǒng)的實(shí)現(xiàn)機(jī)制。系統(tǒng)的組合是在編譯時靜態(tài)組裝還是運(yùn)行時動態(tài)進(jìn)行。對程序單元分別進(jìn)行編譯的模塊化編譯機(jī)制。對組裝結(jié)果的驗(yàn)證機(jī)制等。19AOP的本質(zhì)

將橫切關(guān)注點(diǎn)(如日志、權(quán)限驗(yàn)證、并發(fā)控制等非功能需求)單獨(dú)用aspect實(shí)現(xiàn),而業(yè)務(wù)功能用現(xiàn)有的軟件技術(shù)實(shí)現(xiàn)。由AOP機(jī)制提供將這些分離的關(guān)注點(diǎn)編織為一個可執(zhí)行程序。提高代碼的可理解性、可維護(hù)性、可復(fù)用性等。橫切關(guān)注點(diǎn)20AOP系統(tǒng)的軟件開發(fā)過程業(yè)務(wù)邏輯存儲日志安全需求關(guān)注點(diǎn)標(biāo)識編織器Aspect分解Aspect重組21AOP與OOP比較OOP是AOP的技術(shù)基礎(chǔ),AOP是對OOP的繼承和發(fā)展??蓴U(kuò)展性:指軟件系統(tǒng)在需求更改時程序的易更改能力。OOP主要通過提供繼承和重載機(jī)制來提高軟件的可擴(kuò)展性。

AOP通過擴(kuò)展Aspect或增加Aspect,系統(tǒng)相關(guān)的各個部分都隨之產(chǎn)生變化。22可重用性:指某個應(yīng)用系統(tǒng)中的元素被應(yīng)用到其他應(yīng)用系統(tǒng)的能力。

OOP以類機(jī)制作為一種抽象的數(shù)據(jù)類型,提供了比過程化更好的重用性。OOP的重用性對非特定于系統(tǒng)的功能模塊有很好的支持,如堆棧的操作和窗口機(jī)制的實(shí)現(xiàn)。對于不能封裝成類的元素,如異常處理等,很難實(shí)現(xiàn)重用。AOP使不能封裝成類的元素的重用成為可能。23易理解性和易維護(hù)性代碼纏結(jié)問題的存在,使OOP技術(shù)在易理解性和易維護(hù)性方面都難有很大的提高。統(tǒng)計發(fā)現(xiàn):“如果一個他人寫的程序有37處需要改動,對于一個最優(yōu)秀的軟件開發(fā)人員,也大概只能找到35個”。對于AOP,對一個Aspect修改可以通過聯(lián)結(jié)器影響到系統(tǒng)相關(guān)的各個部分,從而大大提高系統(tǒng)的易維護(hù)性。24AOP特性Aspect的實(shí)現(xiàn)和傳統(tǒng)開發(fā)方法中模塊的實(shí)現(xiàn)不同。Aspect的開發(fā)彼此獨(dú)立,是一種松耦合關(guān)系。主代碼的開發(fā)者甚至可能沒有意識到aspect的存在。只是在最后系統(tǒng)組裝時,才將各aspect代碼和主代碼編排融合在一起。主代碼和Aspect之間采用“隱式調(diào)用”。某一應(yīng)用的領(lǐng)域?qū)<?,不太可能對分布、認(rèn)證、訪問控制、同步、加密、冗余等問題的復(fù)雜實(shí)現(xiàn)機(jī)制很熟悉,所以就不能保證他們在程序中進(jìn)行正確的調(diào)用。開發(fā)人員很難正確預(yù)見到未來對程序的新需求。25AspectJAspectJ是XeroxPARC開發(fā)的基于Java語言的AOP擴(kuò)展,它既是一種規(guī)約語言,也是一種AOP的實(shí)現(xiàn)語言。AspectJ是一種支持“面向Aspect”概念的語言。26AspectJAspectJ提供了支持“面向Aspect”概念的如下語言結(jié)構(gòu)及定義:Joinpoints:預(yù)定義好的程序的特定執(zhí)行點(diǎn)。例如:方法的調(diào)用和執(zhí)行對屬性的讀寫訪問異常處理對象和類的初始化執(zhí)行構(gòu)造器的調(diào)用和執(zhí)行27Pointcuts:用來指明所需連接點(diǎn)的語言元素??赡馨ㄒ幌盗械倪B接點(diǎn),同時它還可以為在連接點(diǎn)上執(zhí)行的通知提供上下文。例如:

pointcutcallSetter();call(publicvoidHelloWorld.set*(..))。其中:

pointcut說明聲明的是一個切入點(diǎn),命名callSetter,后面的空括號表示該切入點(diǎn)不需要上下文信息。

Call表示該切入點(diǎn)捕獲的是對指定方法的調(diào)用,指定的方法是在類HelloWorld中聲明的共有的、返回值為空、以set開頭、擁有任意參數(shù)的方法。28Advices:要在Pointcuts執(zhí)行的Aspect的代碼。

AspectJ提供了3種把通知關(guān)聯(lián)到連接點(diǎn)的方式:after、before、around。after和before分別表示通知在連接點(diǎn)的前面或者后面運(yùn)行,around則表示通知在連接點(diǎn)的外面運(yùn)行,并可以決定是否運(yùn)行此連接點(diǎn)。例如:在銀行信息系統(tǒng)中,實(shí)現(xiàn)帳戶存取模塊、權(quán)限驗(yàn)證模塊和日志記錄模塊。帳戶存取模塊可用OOP技術(shù)來實(shí)現(xiàn),其他的模塊可采用AOP技術(shù)。

在around通知中驗(yàn)證權(quán)限,只有驗(yàn)證通過才運(yùn)行該連接點(diǎn),在before和after通知中就輸出日志記錄。Aspect:上述三者的結(jié)合。以類似于類的概念,將Pointcut和Advice組合在一起,形成一個程序單元。29AspectJ為程序員提供了編譯、調(diào)試等工具。Aspect編排器將不同aspect組裝到一起。Aspect調(diào)試器獨(dú)立的Aspect瀏覽器和一些流行的IDE環(huán)境(Forte、Jbuilder、Emacs)的集成。AspectJ可以引入新的數(shù)據(jù)成員和新的方法。30應(yīng)用示例1:一個簡單的使用面向?qū)ο蠓椒ㄔO(shè)計的圖元編輯器的示例。在該圖元編輯器中,抽象圖元類FigureElement有兩個圖元子類Point和Line,分別對點(diǎn)和線進(jìn)行管理。這兩個類體現(xiàn)了良好的模塊性,類中源代碼都緊密相關(guān),內(nèi)聚度很高,并且每個類的接口都很清晰。顯示更新的需求:無論圖元何時移動、移動到哪里,都要通知屏幕管理器(Display)其位置發(fā)生了改變。31

采用面向?qū)ο蟮脑O(shè)計方法,典型的做法是在每個移動圖元的操作代碼中,都插入一段通知Display其位置發(fā)生了改變的代碼(調(diào)用Display.update()方法),如圖所示。ClassLine{privatePoint_p1,_p2;PointgetP1(){return_p1;}PointgetP2(){return_p2;}voidsetP1(Pointp1){ this._p1=p1;

Display.update();}voidsetP2(Pointp2){ this._p2=p2;

Display.update();}}ClassPoint{privateint_x1,_x2;intgetX(){return_x1;}intgetY(){return_x2;}voidsetX(intx1){ this._x1=x1;

Display.update();}voidsetY(intx2){ this._x2=x2;

Display.update();}}32AspectDisplayUpdating{Pointcutmove():call(voidLine.setP1(Point))||call(voidLine.setP2(Point))||call(voidPoint.setX(int))||call(voidPoint.setY(int));after()returning:move(){

Display.update();}}ClassLine{

privatePoint_p1,_p2;

PointgetP1(){return_p1;}

PointgetP2(){return_p2;}

voidsetP1(Pointp1){

this._p1=p1;

}

voidsetP2(Pointp2){

this._p2=p2;

}

}

ClassPoint{

privateint_x1,_x2;

intgetX(){return_x1;}

intgetY(){return_x2;}

voidsetX(intx1){

this._x1=x1;

}

voidsetY(intx2){

this._x2=x2;

}

}

33假設(shè)我們想用aspect做以下的事情:在任何對象調(diào)用TestClass.sayHello()方法的前后打印一條消息。測試TestClass.sayAnyThing()方法的參數(shù)至少有三個字符。publicclassTestClass{publicvoidsayHello(){System.out.println(“Hello,AOP”);}publicvoidSayAnyThing(Strings){system.out.println(s);)publicstaticvoidmain(String[]args){TestClasst=newTestClass();t.sayHello();t.sayAnyThing(“ok”);}}

應(yīng)用234publicaspectMyAspect{publicpointcutsayMethodCall():

call(publicvoidTestClass.say*());pub1icpointcutsayMethodCal1Arg(Stringstr):

call(publicvoidTestClass.sayAnyThing(string))&&args(str);before():sayMethodCal1(){System.out.print1n(“\nTestClass.”+thisJoinPointStaticPart.getSignature().getName()+”start…”);}after():sayMethodCal1(){System.out.print1n(“\nTestClass.”+thisJoinPointStaticPart.getSignature().getName()+”end…”);}before(Stringstr):sayMethodCallArg(str){if(str.1ength()3){System.out.println(“Error:Ican’tsaywordslessthan3characters”);

return;

}}35應(yīng)用示例3:例外處理

以數(shù)據(jù)庫查詢?yōu)槔?,分別用OOP的Java語言和AOP的AspectJ語言加以實(shí)現(xiàn)。

publicclassDBQuery{

publicResultSetexecuteQuery(Stringsql){

try{

//數(shù)據(jù)庫連接操作

//數(shù)據(jù)庫查詢操作 }catch(java.lang.ClassNotFoundExceptione){

//對ClassNotFound例外進(jìn)行處理 }catch(SQLExceptione){

//對SQL例外進(jìn)行處理 }catch(Exceptione){

//對其他例外進(jìn)行處理 } }}36分析以上代碼,主要存在以下幾點(diǎn)不足:要求編程人員掌握大量的例外類庫和復(fù)雜的語法結(jié)構(gòu),實(shí)際應(yīng)用中容易出錯;對例外的處理并不是DBQuery類的核心功能,但編程人員要花費(fèi)大量精力在例外的處理上,而忽略了問題本身;當(dāng)DBQuery所在類包中定義了多個類或DBQuery中定義了多個方法時(如數(shù)據(jù)庫記錄的添加、更新、刪除等操作),就要重復(fù)定義多個相同的例外處理;大量的例外處理代碼可能引起更多的不必要錯誤,給程序調(diào)試和維護(hù)帶來了困難;基于以上幾點(diǎn),可認(rèn)為它是有安全隱患和不健壯的程序。37

基于AOP安全編程的思想,在DBQuery類中保留單純的數(shù)據(jù)庫連接和查詢代碼,而將其中實(shí)現(xiàn)例外處理的代碼抽取出來,組織成單獨(dú)模塊。

38aspectExHandle{

declaresoft:Exception:within(DBQuery);

pointcutCallmethod(DBQueryquery):this(query)&&call(**

DBQuery.*(..));

after(DBQueryquery)throwing(java.lang.ClassNotFoundExceptione):Callmethod(query){

//對ClassNotFound例外進(jìn)行處理 }

after(DBQueryquery)throwing(SQLExceptione):Callmethod(query){

//對SQL例外進(jìn)行處理 }

after(DBQueryquery)throwing(Exceptione):Callmethod(query){

//對其它例外進(jìn)行處理 }}39

以下幾方面為突出的安全優(yōu)點(diǎn):程序開發(fā)人員可專注于數(shù)據(jù)庫連接和查詢操作本身,而無須同時考慮對例外的處理;安全代碼被獨(dú)立到單獨(dú)的aspect中,使程序更易理解,且當(dāng)安全策略需要修改時,只需變動ExHandle代碼,而無需改動DBQuery類;當(dāng)添加新的類或DBQuery類中添加新的方法時,編程人員不必考慮新的錯誤處理策略,甚至不必去了解這些策略,ExHandle代碼將自動應(yīng)用于它們。40應(yīng)用4:一個異常處理的實(shí)例

下面的代碼是一個簡單的方面的例子,它打印所有的沒有被包中定義的任何方法處理的異常。我們能在測試時使用這個代碼,看是否有沒預(yù)料到的錯誤,由此指出包中的一個漏洞。

publicaspectExceptionPrinter { pointcutallMethods():executions(**(..));

staticafter()throwing(Exceptione):allMethods() { System.out.println(“Uncaughtexception:”+e);

} }41應(yīng)用5:AOP技術(shù)在并發(fā)訪問控制中的應(yīng)用當(dāng)多個線程要訪問同一個變量或?qū)ο髸r,為了保證數(shù)據(jù)的一致性,要實(shí)施一些并發(fā)訪問控制策略。通常的做法是采用加鎖和解鎖的方法。即多個訪問類同時訪問一個共享數(shù)據(jù)對象時,每個訪問類在訪問這個數(shù)據(jù)對象時,將數(shù)據(jù)對象上鎖,訪問完成后,再解鎖,供其他并發(fā)線程訪問。workerAnotherworker數(shù)據(jù)對象上鎖解鎖上鎖解鎖42publicaspectLock{ReentrantWriterPreferenceReadWriteLockrwl=newReentrantWriterPreferenceReadWriteLock();publicpointcutwriteOperations():execution(publicbooleanWorker.createData())||

execution(publicbooleanWorker.updateData())||execution(publicbooleanAnotherWorker.updateData());before():writeOperations(){ rwl.writeLock().acquire();//在寫操作之前上鎖after():writeOperations(){ rwl.writeLock().release();//在寫操作之后解鎖}}43AOP研究內(nèi)容Earlyaspects:aspect-orientedrequirementsengineeringandarchitecturedesign.Aspect-orientedmodelinganddesignDesignpatternsforaspect-orientedsystems

44Aspect-orientedprogramminglanguages,platformsandframeworksTypesystemsforaspectsCompositionmodelsandoperatorsforaspectsOptimizationandperformanceimprovementofaspect-orientedcomposition45ApplicationofAOSDinspecificareassuchasembeddedsystems,b

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論