面向方面的程序设计.ppt
- 文档编号:18719083
- 上传时间:2023-10-18
- 格式:PPT
- 页数:56
- 大小:1.32MB
面向方面的程序设计.ppt
《面向方面的程序设计.ppt》由会员分享,可在线阅读,更多相关《面向方面的程序设计.ppt(56页珍藏版)》请在冰点文库上搜索。
1,面向方面的程序设计兼谈计算科学的创新,2,面向方面的程序设计,Aspectorientedprogramming(AOP),3,Xerox(施乐)公司PARC研究中心在1997年的欧洲面向对象编程大会(ECOOP97)上首次提出Aspect-orientedprogramming(AOP)。
自2002年起,每年分别在欧洲和美国轮流召开专门的面向方面软件开发(AOSD)国际会议。
与会者包括美国、加拿大、荷兰、英国、法国、丹麦、日本、以色列等。
我国一些学校也对AOP给以关注并开展了一些研究工作。
从AOP概念提出经过了近十年的时间,这种技术现在已经开始被工业界采用。
4,AOP产生的背景,计算机软件设计的一个重要原则,就是要清晰分离各种关注点(separationofconcerns),然后分而治之,各个击破,最后形成统一的解决方案。
5,关注点:
是指一个特定的目标、概念或者兴趣域。
从技术的角度,软件系统分别包括核心级和系统级的关注点。
核心级关注点是系统要完成的业务功能;系统级关注点是完成核心级关注点所必须的配套设施,这些配套设施通常被认为是整个系统的系统特性,或者是业务功能的功能约束。
例如:
信用卡处理系统核心关注点是处理付款;系统级关注点包括日志、事务、认证、安全和性能等等。
6,软件系统中,某个行为,例如操作日志的记录,存在于软件的各个部分中,这个行为可以看作是横向存在于软件之中,他所关注的是软件的各个部分的一些共有的行为。
在很多情况下,这种行为不属于业务逻辑的一部分。
这种操作并不是业务逻辑调用的必须部分,但是,我们却往往不得在代码中显式进行调用,并承担由此带来的后果。
7,在目前的技术框架下,通常系统级关注点在逻辑上相互之间彼此正交(相互独立),同时在实现上趋向于和若干核心模块交织。
例如:
信用卡管理系统的每个核心业务关注点都和安全、日志等系统关注点相联系。
8,核心级关注点(业务)多数情况下可以被很好地分解,并通过编程语言模块化实现(子模块或软构件)。
系统级关注点(横向关注点),使用当前的程序设计方法导致在许多构件中要重复包含(扩散)这些代码。
9,横切示例(crosscutting),Authentication权限Caching缓存Contextpassing内容传递Errorhandling错误处理Lazyloading懒加载Debugging调试Logging、tracing、profilingandmonitoring日志、跟踪、优化、校准Performanceoptimization性能优化Persistence持久化Resourcepooling资源池Synchronization同步Transactions事务,10,现有软件技术的不足,目前的实现技术只提供了一维方法学实现系统的关注点,该单一维度一般是核心需求和关注点的模块化实现,其他类型的需求也被迫和该主导维度一致。
问题空间是n维的,而解空间是一维的。
这种失配必然导致需求和实现之间的失配。
11,源程序就会变成一些为不同关注目的而编制的指令的缠结混乱物。
缠结现象是现有软件系统中许多不必要的复杂性的核心。
它增加了功能构件之间的依赖性,分散了构件原来假定要做的事情,提供了许多程序设计出错的机会,使得一些功能构件难以复用,源代码难以开发、理解和发展。
12,某一应用的领域专家,不太可能对分布、认证、访问控制、同步、加密、冗余等问题的复杂实现机制很熟悉,所以就不能保证他们在程序中进行正确的调用。
开发人员很难正确预见到未来对程序的新需求。
13,方面(Aspect),设计上讲,是横切系统的一些软件系统级关注点。
实现上讲,它支持将横切系统的关注点封装在单独的模块单位中,它是AOP将横切关注点局部化和模块化的实现机制。
常见的“方面”:
异常和出错处理同步和并发控制内存访问模式日志、安全事务、性能,14,AOP核心内容就是所谓的“横切关注点”,即“方面”,Aspect是AOP提供的一种程序设计单元。
而在OOP中,这些一般关注点的实现单元叫作类AOP的目标,是要将这些横切关注点与业务逻辑代码相分离,从而得到更好的软件结构、性能以及稳定性等方面的好处。
AOP被认为是后面向对象时代的一种新的重要的程序设计技术。
15,AOP的基本思想,通过分别描述系统的不同关注点及其关系,以一种松耦合的方式实现单个关注点,然后依靠AOP环境的支撑机制,将这些关注点组织或编排成最终的可运行程序。
普通关注点可以使用传统的结构化方法和面向对象方法体统的机制。
系统关注点使用Aspect机制。
16,AOP程序设计的一般步骤,一、对需求规约进行Aspect分解。
确定哪些功能是组件必须实现的,即提取出核心关注点。
哪些功能可以以aspect的形式动态加入到系统组件中去,即提取出系统级的横切关注点。
17,AOP程序设计的一般步骤,二、对标识出的Aspect分别通过程序机制实现。
构造系统的组件。
利用组件语言实现系统的组件。
对于OOP语言,这些组件可以是类;对于过程化程序设计语言,这些组件可以是各种函数和API。
构造系统的aspect。
利用一种或多种aspect语言实现aspect。
aspect语言必须提供声明aspect的机制。
aspect如何声明连接点如何定义aspect代码如何定义aspect的参数化程度等,18,三、用aspect编织器将所有的单元编排重组在一起,形成最终的可运行系统。
为组件语言和aspect语言构造相应的语法树;依据aspect中的连接点定义对语法树进行联结;在连接的语法树上生成中间文件或目标代码。
aspect语言必须提供将aspect代码和基础代码组合编排(weaving)在一起的机制。
定义编排语言和规则。
解决aspect之间潜在的冲突。
为组装和执行建立外部约束。
aspect语言必须提供生成可运行系统的实现机制。
系统的组合是在编译时静态组装还是运行时动态进行。
对程序单元分别进行编译的模块化编译机制。
对组装结果的验证机制等。
19,AOP的本质,将横切关注点(如日志、权限验证、并发控制等非功能需求)单独用aspect实现,而业务功能用现有的软件技术实现。
由AOP机制提供将这些分离的关注点编织为一个可执行程序。
提高代码的可理解性、可维护性、可复用性等。
横切关注点,20,AOP系统的软件开发过程,21,AOP与OOP比较,OOP是AOP的技术基础,AOP是对OOP的继承和发展。
可扩展性:
指软件系统在需求更改时程序的易更改能力。
OOP主要通过提供继承和重载机制来提高软件的可扩展性。
AOP通过扩展Aspect或增加Aspect,系统相关的各个部分都随之产生变化。
22,可重用性:
指某个应用系统中的元素被应用到其他应用系统的能力。
OOP以类机制作为一种抽象的数据类型,提供了比过程化更好的重用性。
OOP的重用性对非特定于系统的功能模块有很好的支持,如堆栈的操作和窗口机制的实现。
对于不能封装成类的元素,如异常处理等,很难实现重用。
AOP使不能封装成类的元素的重用成为可能。
23,易理解性和易维护性代码缠结问题的存在,使OOP技术在易理解性和易维护性方面都难有很大的提高。
统计发现:
“如果一个他人写的程序有37处需要改动,对于一个最优秀的软件开发人员,也大概只能找到35个”。
对于AOP,对一个Aspect修改可以通过联结器影响到系统相关的各个部分,从而大大提高系统的易维护性。
24,AOP特性,Aspect的实现和传统开发方法中模块的实现不同。
Aspect的开发彼此独立,是一种松耦合关系。
主代码的开发者甚至可能没有意识到aspect的存在。
只是在最后系统组装时,才将各aspect代码和主代码编排融合在一起。
主代码和Aspect之间采用“隐式调用”。
某一应用的领域专家,不太可能对分布、认证、访问控制、同步、加密、冗余等问题的复杂实现机制很熟悉,所以就不能保证他们在程序中进行正确的调用。
开发人员很难正确预见到未来对程序的新需求。
25,AspectJ,AspectJ是XeroxPARC开发的基于Java语言的AOP扩展,它既是一种规约语言,也是一种AOP的实现语言。
AspectJ是一种支持“面向Aspect”概念的语言。
26,AspectJ,AspectJ提供了支持“面向Aspect”概念的如下语言结构及定义:
Joinpoints:
预定义好的程序的特定执行点。
例如:
方法的调用和执行对属性的读写访问异常处理对象和类的初始化执行构造器的调用和执行,27,Pointcuts:
用来指明所需连接点的语言元素。
可能包括一系列的连接点,同时它还可以为在连接点上执行的通知提供上下文。
例如:
pointcutcallSetter();call(publicvoidHelloWorld.set*(.)。
其中:
pointcut说明声明的是一个切入点,命名callSetter,后面的空括号表示该切入点不需要上下文信息。
Call表示该切入点捕获的是对指定方法的调用,指定的方法是在类HelloWorld中声明的共有的、返回值为空、以set开头、拥有任意参数的方法。
28,Advices:
要在Pointcuts执行的Aspect的代码。
AspectJ提供了3种把通知关联到连接点的方式:
after、before、around。
after和before分别表示通知在连接点的前面或者后面运行,around则表示通知在连接点的外面运行,并可以决定是否运行此连接点。
例如:
在银行信息系统中,实现帐户存取模块、权限验证模块和日志记录模块。
帐户存取模块可用OOP技术来实现,其他的模块可采用AOP技术。
在around通知中验证权限,只有验证通过才运行该连接点,在before和after通知中就输出日志记录。
Aspect:
上述三者的结合。
以类似于类的概念,将Pointcut和Advice组合在一起,形成一个程序单元。
29,AspectJ为程序员提供了编译、调试等工具。
Aspect编排器将不同aspect组装到一起。
Aspect调试器独立的Aspect浏览器和一些流行的IDE环境(Forte、Jbuilder、Emacs)的集成。
AspectJ可以引入新的数据成员和新的方法。
30,应用示例1:
一个简单的使用面向对象方法设计的图元编辑器的示例。
在该图元编辑器中,抽象图元类FigureElement有两个图元子类Point和Line,分别对点和线进行管理。
这两个类体现了良好的模块性,类中源代码都紧密相关,内聚度很高,并且每个类的接口都很清晰。
显示更新的需求:
无论图元何时移动、移动到哪里,都要通知屏幕管理器(Display)其位置发生了改变。
31,采用面向对象的设计方法,典型的做法是在每个移动图元的操作代码中,都插入一段通知Display其位置发生了改变的代码(调用Display.update()方法),如图所示。
ClassLineprivatePoint_p1,_p2;PointgetP1()return_p1;PointgetP2()return_p2;voidsetP1(Pointp1)this._p1=p1;Display.update();voidsetP2(Pointp2)this._p2=p2;Display.update();,ClassPointprivateint_x1,_x2;intgetX()return_x1;intgetY()return_x2;voidsetX(intx1)this._x1=x1;Display.update();voidsetY(intx2)this._x2=x2;Display.update();,32,AspectDisplayUpdatingPointcutmove():
call(voidLine.setP1(Point)|call(voidLine.setP2(Point)|call(voidPoint.setX(int)|call(voidPoint.setY(int);after()returning:
move()Display.update();,ClassLineprivatePoint_p1,_p2;PointgetP1()return_p1;PointgetP2()return_p2;voidsetP1(Pointp1)this._p1=p1;voidsetP2(Pointp2)this._p2=p2;ClassPointprivateint_x1,_x2;intgetX()return_x1;intgetY()return_x2;voidsetX(intx1)this._x1=x1;voidsetY(intx2)this._x2=x2;,33,假设我们想用aspect做以下的事情:
在任何对象调用TestClass.sayHello()方法的前后打印一条消息。
测试TestClass.sayAnyThing()方法的参数至少有三个字符。
publicclassTestClasspublicvoidsayHello()System.out.println(“Hello,AOP”);publicvoidSayAnyThing(Strings)system.out.println(s);)publicstaticvoidmain(Stringargs)TestClasst=newTestClass();t.sayHello();t.sayAnyThing(“ok”);,应用2,34,publicaspectMyAspectpublicpointcutsayMethodCall():
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:
Icantsaywordslessthan3characters”);return;,35,应用示例3:
例外处理,以数据库查询为例,分别用OOP的Java语言和AOP的AspectJ语言加以实现。
publicclassDBQuerypublicResultSetexecuteQuery(Stringsql)try/数据库连接操作/数据库查询操作catch(java.lang.ClassNotFoundExceptione)/对ClassNotFound例外进行处理catch(SQLExceptione)/对SQL例外进行处理catch(Exceptione)/对其他例外进行处理,36,分析以上代码,主要存在以下几点不足:
要求编程人员掌握大量的例外类库和复杂的语法结构,实际应用中容易出错;对例外的处理并不是DBQuery类的核心功能,但编程人员要花费大量精力在例外的处理上,而忽略了问题本身;当DBQuery所在类包中定义了多个类或DBQuery中定义了多个方法时(如数据库记录的添加、更新、删除等操作),就要重复定义多个相同的例外处理;大量的例外处理代码可能引起更多的不必要错误,给程序调试和维护带来了困难;基于以上几点,可认为它是有安全隐患和不健壮的程序。
37,基于AOP安全编程的思想,在DBQuery类中保留单纯的数据库连接和查询代码,而将其中实现例外处理的代码抽取出来,组织成单独模块。
38,aspectExHandledeclaresoft:
Exception:
within(DBQuery);pointcutCallmethod(DBQueryquery):
this(query)&call(*DBQuery.*(.);after(DBQueryquery)throwing(java.lang.ClassNotFoundExceptione):
Callmethod(query)/对ClassNotFound例外进行处理after(DBQueryquery)throwing(SQLExceptione):
Callmethod(query)/对SQL例外进行处理after(DBQueryquery)throwing(Exceptione):
Callmethod(query)/对其它例外进行处理,39,以下几方面为突出的安全优点:
程序开发人员可专注于数据库连接和查询操作本身,而无须同时考虑对例外的处理;安全代码被独立到单独的aspect中,使程序更易理解,且当安全策略需要修改时,只需变动ExHandle代码,而无需改动DBQuery类;当添加新的类或DBQuery类中添加新的方法时,编程人员不必考虑新的错误处理策略,甚至不必去了解这些策略,ExHandle代码将自动应用于它们。
40,应用4:
一个异常处理的实例,下面的代码是一个简单的方面的例子,它打印所有的没有被包中定义的任何方法处理的异常。
我们能在测试时使用这个代码,看是否有没预料到的错误,由此指出包中的一个漏洞。
publicaspectExceptionPrinterpointcutallMethods():
executions(*();staticafter()throwing(Exceptione):
allMethods()System.out.println(“Uncaughtexception:
”+e);,41,应用5:
AOP技术在并发访问控制中的应用,当多个线程要访问同一个变量或对象时,为了保证数据的一致性,要实施一些并发访问控制策略。
通常的做法是采用加锁和解锁的方法。
即多个访问类同时访问一个共享数据对象时,每个访问类在访问这个数据对象时,将数据对象上锁,访问完成后,再解锁,供其他并发线程访问。
42,publicaspectLockReentrantWriterPreferenceReadWriteLockrwl=newReentrantWriterPreferenceReadWriteLock();publicpointcutwriteOperations():
execution(publicbooleanWorker.createData()|execution(publicbooleanWorker.updateData()|execution(publicbooleanAnotherWorker.updateData();before():
writeOperations()rwl.writeLock().acquire();/在写操作之前上锁after():
writeOperations()rwl.writeLock().release();/在写操作之后解锁,43,AOP研究内容,Earlyaspects:
aspect-orientedrequirementsengineeringandarchitecturedesign.Aspect-orientedmodelinganddesignDesignpatternsforaspect-orientedsystems,44,Aspect-orientedprogramminglanguages,platformsandframeworksTypesystemsforaspectsCompositionmodelsandoperatorsforaspectsOptimizationandperformanceimprovementofaspect-orientedcomposition,45,ApplicationofAOSDinspecificareassuchasembeddedsystems,bankingsystems,ambientcomputing,etc.Aspectsinfeature-orientedapproachesandproductlines.Aspectsinreengineering,46,小结,AOP起源于程序设计中“横切”引发的“代码散布”和“代码交织”问题。
在目前的程序设计技术下,程序中的横切无法避免,其实现代码相互纠缠在一起,是软件复杂度的来源之一。
AOP就是要能分离出那些隐含的、相互交织纠缠的系统关注点,并使之明确。
使用AOP为程序员提供的新的模块化武器,横切的代码就可以局部化,程序的结构很明白,代码也常常很简短。
47,面向方面不仅在增加分割系统特性上的价值对基本系统的安全性、日志、持久性、调试、跟踪、分布式、执行监控等。
方面的另一个重要的目的是提供了一个把用例与方面连接起来的新范型。
(在现存的构件模块性的顶端增加用例模块),48,子用例,异常用例,异常用例,异常用例,基本用例,面向方面技术也使UML中用例模块化,49,子用例,异常用例,异常用例,异常用例,基本用例,编织器,50,可以肯定的是:
AOP不会是处理关注点分离问题的最后解决方案。
如果AOP对系统关注点的分离粒度太细,则会适得其反,导致模块间关系更加复杂,反而使复杂度增加。
因此,应用AOP时仍然要遵从良好的设计原则,只分离需要分离的关注点。
51,AOP的概念也就是面向方面的软件开发(AOSD)将会使我们可以完美的继承已经存在的软件,在系统的整个生命周期中,可以不断的进行开发迭代和不断的发布更新版本。
我们今天叫做面向方面的技术将把软件生命周期成本降低至少20。
52,它与“子程序”概念十分相像,但是不是所有的关注点都能很利索地通过子程序实现。
子程序调用的程序员必须对调用的子程序有足够的了解。
一段程序必须知道要显式地调用另一段子程序,并且知道怎样去调用,这极大限制了程序员并行独立解决子问题的能力。
53,这不是一种横空出世的新思想,它依赖于十年前就已经众所周知的补丁技术(补丁技术已成为专利技术!
)。
然而什么是新的呢?
就是实现了“正确地打补丁”,把补丁技术系统化、抽象化和形式化,这正是理解复杂系统的最自然方式。
54,反向思维,保持原衣服不动,把在何处打补丁的信息写在补丁上。
大部分创新的基本思想都来自日常生活,而且原理简单,打补丁反向打补丁系统化、抽象化、形式化,实现两次创新!
55,希望寄托在年轻人身上!
56,谢谢,再见,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 面向 方面 程序设计