21种设计模式集合学习笔记

21种设计模式集合学习笔记

①代理设计模式

一.代理设计模式的概念:为对象提供一个代理,以控制对这个对象的访问。代理类和委托类有共同的付接口,这样在任何使用为拖累对象的地方都可以使用代理类进行替代。

类似于明星和经纪人。明星是具体的委托类,经纪人则是代理类。代理类负责请求的预处理(谈价格,),然后把业务交给委托类(明星),然后业务完成后,代理类完成后续处理(收尾款)。

代理模式看起来和包装模式非常类似,但是其实截然不同:
1.目的:代理模式目的是为了解除耦合性,而包装模式则是在原有对象的功能上进行包装,比如IO流中的各种包装类型的流
2.写法,代理模式中代理类和委托类实现同一接口,通过工厂类来实现获取代理类,而包装类是通过包装类继承原生类,来提高代码的复用率

二.代理分为静态代理和动态代理,静态代理由于每一个委托类都需要生成一个代理类,我们不做详细介绍,下面介绍动态代理

动态代理的思想就是,采用一个工厂类,动态的生成不同的委托类的不同代理类,不存在代理类实体
举个例子,就在Web应用中,我们有的服务层需要开启事务有的不需要开启事务,如果直接在业务层实现开启事物的代码,就会导致在service层直接操控数据库,提高了代码的耦合性,因此我们可以提供一个代理类,通过Servlet调用代理类,代理类代理Service,如果Service层的方法体上有提示需要使用动态代理的注释。在代理类中进入开启事务的分支,如果不需要,就进入不需要开启事务的分支。
(为什么要采用注解来区分调用代理类不同方法的原因是:方法中的局部变量在外部不能访问,所以,我们只能通过注解来区分不同方法的代理。)

三.Java中的专门生成动态代理类的API:

java.lang.reflect.Proxy
简化后的动态代理实现
// InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
InvocationHandler handler = new InvocationHandlerImpl(..);

// 通过 Proxy 直接创建动态代理类实例
T proxy = (T)Proxy.newProxyInstance( classLoader,
new Class[] { Interface.class }, handler );
classLoader表示类加载器,一般来说是指委托类的类加载器,因为需要加载该类,并且生成新的代理类。
第二个参数表示该类所实现的所有接口,因为委托类和代理类必须实现同样的接口。
第三个参数实际上是对代理类进行的操作。

举个小例子,假如方法上有一个注解Tran,则在方法启动时,先开启事物,在方法结束后,提交事物.
如果没有,则只结束事务。

T proxy = (T) Proxy.newProxyInstance(clz.getClassLoader(),clz.getInterfaces(), new InvocationHandler() 
{
                            // 1.类加载器 2.类实现的接口 3.对类中方法实现的操作.
                            public Object invoke(Object proxy, Method method,
                                    Object[] args) throws Throwable {
                                // TODO Auto-generated method stub
                                Object result = null;
                                if (method.isAnnotationPresent(Tran.class)) {
                                    // 这里的类实现了Tran注释,需要开启事务

                                    try {
                                        TranManager.startTran();
                                        result = method.invoke(t, args);
                                        TranManager.commitTran();
                                    } catch (InvocationTargetException e) {
                                        TranManager.rollBackTran();
                                        throw e.getTargetException();

                                    } finally {
                                        TranManager.realseTran();   
                                    }

                                } else {
                                    try {
                                        result = method.invoke(t, args);
                                    } catch (InvocationTargetException e) {

                                        throw e.getTargetException();

                                    } finally {
                                        TranManager.realseTran();
                                    }
                                }
                                return result;
                            }

                        });

你可能感兴趣的:(学习笔记)