上篇我们将了一下代理模式的静态代理,然后碰到一个代码重复的问题。
回头在来看下我们用代理实现事务的封装,它们都遵循这样的一个结构:
System.out.println("------获取连接------");
System.out.println("------开户事务------");
方法调用
System.out.println("------提交事务------");
System.out.println("------关闭连接------");
下面我们就再来回想一个叫做模板方法的设计模式吧。这个设计模式有两种用途:封装算法步骤和提取公共部分。现在我们要用的是这个设计模式的提取公共部分。
PS:比较可惜的是,我看源码没有搞明白代理这块的具体实现,只是按照个人对设计模式的一种理解来分析一下而已。
这些结构不只是上面的形式,还有方法名、参数、返回值,每个类都有实现的接口。
个人对动态代理的理解就是用了一个模板方法来进行的实现,提取一个公共的InvocationHandler接口,这个接口中有一个invoke方法,方法的参数分别是Proxy,Method,args。通过Method可以获取到要执行的方法,也就是把需要变更的东西都进行了抽取。
这样,就实现了变更的抽取,那么只需要通过method.invoke()方法,就可以调取需要调用的方法。而公共部分的操作,就只需要些一份就足够了。
下面是代码实现,接口和BLL实现类,沿用上篇提到的使用代理后的BLLImpl:
public class TransactionHandler implements InvocationHandler {
private Object targetObject;
public Object newProxyInstance(Object targetObject){
this.targetObject=targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object ret=null;
System.out.println("------获取连接------");
System.out.println("------开户事务------");
ret=method.invoke(targetObject, args);
System.out.println("------提交事务------");
System.out.println("------关闭连接------");
return ret;
}
}
现在,关于事务的代码,只需要维护一份就足够了。
关于模板方法的另一个应用——封装算法步骤,Servlet就是一个很好的例子,有兴趣可以自己看一下究竟怎样封装算法就是用到了模板方法模式。
知道设计模式是一回事,可以应用又是一回事,能够在设计的时候想到设计模式是一件任重而道远的事情。
一款好的软件,一个大的架构,必定是N多个设计模式的结合,三层架构如此,MVC架构也如此。本人关于MVC和三层架构曾经写过一篇博文进行对比,学这块的时候又回头看了一下,就现在而言,当时的理解还是没有太大问题的,博文名称是:详谈架构。