首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

别装了-第一集:署理模式、动态代理和面向方面

2012-11-14 
别装了-第一集:代理模式、动态代理和面向方面????以上我们简单模拟了代理模式的情景和为什么要使用代理模式

别装了-第一集:代理模式、动态代理和面向方面

????以上我们简单模拟了代理模式的情景和为什么要使用代理模式,下面我们以一个例子来具体分析一下JAVA中的代理模式。 ????假设有一个信息管理系统,用些用户有浏览信息的权限,有些用户有浏览、添加和修改信息的权限,还有些用户有除了上述的权限,还有删除信息的权限,那么我们最容易想到的做法如下: 

<!---->

???? 客户端通过调用代理类来执行动作 ,而代理类一是将权限判断和动作的执行分离开来,满足了单一职责原则;二是实现了 同 一个接口,从而满足了依赖颠倒原则。比第一个思路好了很多。 ????代理又被称为 委派 ,说的是代理类 并不真正的执行那个核心动作 ,而是委派给另外一个类去执行,如ProxyView类中,ProxyView类并没有真正执行doAction()方法,而是交给ViewAction类去执行。 ????我们再来看代理类ProxyViewAction,可以看到它不仅依赖于接口Action,而且依赖于具体的实现ViewAction。这样对我们的系统扩展很不利,比如我们有Add动作、Delete动作、Modify动作等等,我们需要对每一个动作都写一个代理类,而这些代理类都做同样的事情,先进行权限判断,然后再委派。所以我们需要对这些代理再进行一次抽象, 让它只依赖接口Action,而不依赖于具体的实现 。 

????而我们的客户端类似如下: Action?action?=?ProxyAction(new?ViewAction); Action.doAction(); ????通过对代理类的 依赖注入 ,我们使得代理类初步有了一定扩展性。但是我们还要看到,这个代理类依赖于某一个确定的接口。这仍然不能满足我们的实际要求,如我们的系统的权限控制一般是整个系统级的,这样系统级的权限控制,我们很难在整个系统里抽象出一个统一的接口,可能会有多个接口,按照上面的代理模式,我们需要对每一个接口写一个代理类,同样,这些类的功能都是一样的。这显然不是一个好地解决办法。 ????基于上面的原因,我们需要解决一个系统在没有统一的接口的情况下,对一些零散的对象的某一些动作使用代理模式的问题。JAVA?API为我们引入了动态代理或动态委派的技术。 ????动态代理的核心是 InvocationHandler接口 ,要使用动态代理就必须实现该接口。这个接口的委派任务是在invoke(Object?proxy,?Method?m,?Object[]?args)方法里面实现的: //invoke是调用的意思 //在调用核心功能之前作一些动作 …… //调用核心功能 m.invoke(obj,?args); //在调用核心功能以后做一些动作 …… ????我们可以看到动态代理其实用的是 反射机制 来调用核心功能的:m.invoke(obj,?args);正是这种反射机制的使用使得我们调用核心功能更加灵活,而 不用依赖于某一个具体的接口,而是依赖于Object对象 。

????下面我们来看客户端: Action?action?=?(Action)ProxyAction.getInstance(new?ViewAction()); Action.doAction(); ????我们可以看到代理类对接口的依赖也转移到了客户端上,这样,代理类不依赖于某个接口。对于同样的代理类ProxyAction,我们也可以有如下的客户端调用: Engine?engine?=?(Engine)ProxyAction.getInstance(new?EngineImpl()); Engine.execute(); ????只要engineImpl类实现了Engine接口,就可以像上面那样使用。

?

????至此,代理模式和动态代理已经告一段落。我们将动态代理引申一点说开去,来作为这篇文章的蛇足。 ????这个话题就是面向方面的编程,或者说AOP。我们看上面的ProxyImpl类,它的两个方法doBegin()和doAfter(),这是做核心动作之前和之后的两个截取段。正是这两个截取段,却是我们AOP的基础。在OOP里,doBegin(),核心动作,doAfter()这三个动作在多个类里始终在一起,但他们所要完成的逻辑却是不同的,如doBegin()可能做的是权限,在所有的类里它都做权限;而在每个类里核心动作却各不相同;doAfter()可能做的是日志,在所有的类里它都做日志。正是因为在所有的类里,doBegin()或doAfter()都做的是同样的逻辑,因此我们需要将它们提取出来,单独分析、设计和编码,这就是我们的AOP的思想。 ????这样说来,我们的动态代理就能作为实现AOP的基础了。好了,就说这么多,关于AOP技术,我们可以去关注关于这方面的知识。 <!----><!----><!----><!----><!----><!----> 的

热点排行