xuesenlin
http://www.jdon.com Oct 27, 2004 11:05 PM 回复
最近这个段时间都是忙于学习 SpringFramework,那东东好样的,只是刚刚学完Struts,Hibernate,有来了这个,呵呵,,感觉挺累的。
“你怎么把这两个不相干的东西撤到一起?” ,确实是这样! 无论从他们的设计,
实现,使用等方面他们是风马牛不相及, 但本人认为从理解的方面看他们有点类似。况且学习要从对比中学呀!这对初学者会有帮助于理解。
重要声明:本人都是用自己的语言写的,有专业术语不对还请大家指出。: - )
就说设计模式 Decorator,也就是装饰模式,这还不好理解? 在原有的东西上进行装饰一下便是装饰了。既然是装饰,你要有主体呀(被修饰的东西),还要有装饰品。但是不管你装饰来装饰去,他的本质是不变的。 就象人带上了面具,但他还是人。墙上打上了油漆,但它还是墙呀。你也许觉得这是废话。 但理解这点很重要(这是跟策略模式Strategy的区别),本人觉得这个是理解好 Decorator 模式很重要的一点。在开发中你经常要增强一个类的功能,或者是撤销一个类的某些功能,但是一个类给众多的功能进行装饰了以后,也许原来的类已经面目全非了,你往往会感到茫然,其实,你主要抓住他的主体,脑子里面时刻要知道你现在所作的工作就是为这个主体进行打扮的工作。
研究过Jive的都知道, 里面的 Filter 就是用了Decorator 设计模式,那么在这个设计里面,它的主体是什么? ForumMessage ,无疑是 ForumMessage 。装饰品当然是Filter 了,所以我们在作这件事情的时候始终是以ForumMessage为核心的,Filter 进行装饰的时候,你千万不要忘记你现在是为ForumMessage而工作!有关于jive研究的文章,网上一大堆,现在看看一个比较简单的 Decorator:
//比如有一个抽象构件:
publicinterface Component {
void operation();
}
//一个具体构件:
publicclass ConcreteComponent implements Component {
publicvoid operation() {
//Write your code here
}
}
//一个抽象装饰:
publicclass Decorator implements Component {
private Component component; //引用
… …. …. …
//商业方法,委派给构件
publicvoid operation() {
component.operation();
}
}
//一个具体装饰:
publicclass ConcreteDecorator extends Decorator {
/**
* 商业方法
*/
publicvoid operation(){
//一些具体的装饰的代码
......
super.operation(); // 主体
//一些具体的装饰的代码
.......
}
}
......
我们主要看看,在ConcreteDecorator 中的operation() 方法,他的父类是委托到component组建来完成的,其实它就是主体, 一些装饰代码都会在这个方法(主体)执行前进行“预处理”或是执行后进行“收尾”。
可不是,从上面很容易就看出了,抽象装饰中的operation() 方法没有在具体的装饰类中进行“全盘”覆盖,因为他用了super.operation(); 这样的语句。可见装饰模式中不管怎么样, 你都要找到类似这个的方法。说明他的主体还在。(这是跟策略模式Strategy的区别)
说了怎么多,不知道大家有没有感觉到ConcreteDecorator类中的operation()方法跟Spring AOP 中的 InvocationHandler 接口的invoke()方法有点相类是呢?
我们来看看要实现 InvocationHandler 时候要重写的invoke()方法:
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
…………………….
result = method.invoke(originalObject, args);
……………………………..
return result;
}
InvocationHandler.invoke 方法将在被代理类的方法被调用之前触发。通过这个方法中,我们可以在被代理类方法调用的前后进行一些处理,如上面代码中所示,InvocationHandler.invoke方法的参数中传递了当前被调用的方法(Method),以及被调用方法的参数。同时,我们可以通过Method.invoke方法调用被代理类的原始方法实现。这样,我们就可以在被代理类的方法调用前后大做文章。(说明:引用了Spring 开发指南中的一段)
在回到装饰模式,其方法operation() 在执行前和执行后,也可以对它大做文章。如此看来, Spring AOP 和 Decorator,从理解层面上来看,确实有点相象,注意:只是理解层面, 而他们的实现完全两马事!
其实主要是大家怎么看待这个问题,按照本人的理解,Spring AOP 也可以说是一种广义的装饰,但它又不是装饰模式。它同样也是对某个方法加上了限制,比如insert() 的时候,你要对它做执行前开启事务和执行后提交或回滚这样的“装饰”。 又比如你也可以对某个人操作资源后做log这样的装饰工作。等等,,
他们的相同之处就这么点。
AOP 也不是什么新的东西,当然如果你的AOP是容器(Jboss 4.0)实现的话, 那么按照上面说的,你的一些方法就会被容器所“装饰”。
如此看来,更多的时候可以理解为 Spring AOP 和一些AOP 容器是在系统级的,容器级的“装饰”。 而装饰模式则是业务级的装饰。 这点其实从客户端也很容易理解。
如果是AOP ,程序员可以放心的写你的代码(即使有点笨也不怕,有AOP护着呢)。 因为系统将在系统运行时候对这段代码进行“装饰”。也就是说,这些装饰不会出现在客户端的代码中,,,而,Decorator模式呢?呵呵,这个时候程序员要有点头脑了,他们要自己组装一些装饰类,按照某一种机制对主体进行装饰。也就是说,这些修饰类要出现在客户端的代码中。看代码就知道了 :--)
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(input);
....//主体是System.in
哦 , 够经典的例子!