装饰模式&动态代理模式

来源:互联网 发布:斗鱼抢票软件作者qq 编辑:程序博客网 时间:2024/04/30 10:21

    装饰模式和代理模式是GoF23种设计模式中的一部份。关于这两种模式的具体定义我不再赘述,网上有很多这方面的资料。我想说的是这两种模式的共通之处。这两种模式都可以用来给已存在的类的方法增加前、后置的代码。
  

   使用装饰模式去扩充原有类的功能时,要求被扩充的类必须继承自一个接口,该接口定义了该类的行为,然后用一个新的装饰类实现这个接口,并将被扩充类的对象定义为一个成员变量,然后在重写接口方法时,调用被扩展类对象的相应方法,并在这个方法调用语句的前后加上部分需要添加的代码。
   

   使用动态代理模式时,同样需要这样一个接口,切代理类也要实现这个接口,JDK1.3以后的版本为我们提供了一个动态代理很好的实现,具体代码如下:


 package quickweb.db;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**************************************************
 * NAME : DBSC.java
 * HISTORY
 * 2007-08-15 shanc  创建文件
 * 注意:这个类是DBManager的代理类,用于在调用DB的DML方法时,加入前后置的

commit,rollback操作
 * 注意:这个类是为了解决webcs中的不能自动提交的问题,但是由于这个问题产生的

根本原因是数据库设计的
 *   不完善,无法用程序来解决这个问题,所以这种方式完全是为了学习

Proxy模式来做的。没什么实际意义
 *************************************************/
public class DBSC implements InvocationHandler{
 
 //需要被代理的类的实例
 private DBManage db = null;
 
 //定义需要代理的方法名的前缀,这里是DML方法
 private static final String[] DMLMethodNames =

{"insert","update","del"};
 
 public DBSupport bind(DBManage db){//创建一个代理类对象
  this.db = db;
  DBSupport proxyDb = (DBSupport) Proxy.newProxyInstance(//固定

写法
    db.getClass().getClassLoader(),
    db.getClass().getInterfaces(),
    this);
  return proxyDb;
 }

 /**
  * 这个方法是接口定义的方法,必须实现
  */
 public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {
  // TODO Auto-generated method stub
  Object obj = null;
  if(this.isDMLMethod(method)){//是需要代理的方法
   db.setAutoCommit(false);//附加操作
   try{
    obj = method.invoke(db, args);//调用真正的DB

方法
    db.commit();//附加操作
   }catch(Exception e){
    db.rollback();//附加操作
   }
  }else{
   obj = method.invoke(db, args);//不是需要代理的方法
  }
  return obj;
 }
 
 private boolean isDMLMethod(Method method){
  for(int i = 0;i<DMLMethodNames.length;i++){//循环判断,看

method的名字是否符合DMLMethodNames中定义的
   String DMLMethodName = DMLMethodNames[i];
   String methodName = method.getName();
   if(methodName != null && !"".equals(methodName) &&

methodName.startsWith(DMLMethodName))
    return true;
  }
  return false;
 }
}

原创粉丝点击