码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式(就) : 结构型模式--代理模式

时间:2014-06-02 09:39:00      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:des   c   style   class   blog   code   

代理模式是比较常见的一种模式,我们平常接触的比较多,比如正向代理和反向代理。

正向代理的代理服务器是和客户端的网络在一起,由代理服务器转发请求和接受结果,比如有的公司的服务器,会过滤掉对外部网络的访问请求;反向代理的代理服务器接受来自客户端的请求,决定讲请求转发给哪个内部服务器进行处理,反向代理的服务器也可能会过滤掉一些不安全的请求,或者不符合验证条件的请求。

所以代理模式的主要目的是控制对象的访问。

 

《java与模式》中代理模式有两种实现方式:一种是静态的实现方式,一种是利用jdk的动态的实现方式。

1. 静态的实现方式

bubuko.com,布布扣

示意性代码:

1
2
3
4
5
6
7
package com.javadesignpattern.Proxy.Static;
 
public abstract class Subject {
     
    abstract public void request();
 
}

  

bubuko.com,布布扣
package com.javadesignpattern.Proxy.Static;

public class RealSubject extends Subject{

    @Override
    public void request() {
        // TODO Auto-generated method stub
        System.out.println(RealSubject.class + ": request method");
    }

}
bubuko.com,布布扣
bubuko.com,布布扣
package com.javadesignpattern.Proxy.Static;

public class ProxySubject extends Subject {

    private Subject subject;

    public ProxySubject(Subject subject) {
        this.subject = subject;
    }

    public ProxySubject() {

    }

    public void preRequest() {
        System.out.println(ProxySubject.class + ": ProxySubject function");
    }

    public void postRequest() {
        System.out.println(ProxySubject.class + ": postRequest function");
    }

    @Override
    public void request() {
        // TODO Auto-generated method stub
        preRequest();
        if(subject == null){
            subject = new RealSubject();
        }
        subject.request();
        postRequest();
    }

}
bubuko.com,布布扣
bubuko.com,布布扣
package com.javadesignpattern.Proxy.Static;

public class Client {
    
    public static void main(String[] args){
        Subject subject = new ProxySubject();
        subject.request();
        
        System.out.println("************************");
        
        Subject subject2 = new ProxySubject(new RealSubject());
        subject2.request();
    }

}
bubuko.com,布布扣

 

2. jdk动态代理

实现jdk的动态代理分成几步: 

1. 代理类实现InvocationHandler接口,实现invoke方法。

2. Proxy类的newProxyInstance方法,传递三个参数,classloader, interface和InvocationHandler对象实例。

示意性代码:

bubuko.com,布布扣
package com.javadesignpattern.Proxy.Dynamic;

public interface UserManager {
    
    public void addUser(String userId, String userName);
    public void delUser(String userId);
    public String findUser(String userId, String userName);
    public void modifyUser(String userId, String userName);

}
bubuko.com,布布扣
bubuko.com,布布扣
package com.javadesignpattern.Proxy.Dynamic;

public class UserManagerImpl implements UserManager{
    
    public void addUser(String userId, String userName) {
        // TODO Auto-generated method stub
        System.out.println("UserManagerImpl.addUser()userId-->"+userId);
    }

    public void delUser(String userId) {
        // TODO Auto-generated method stub
        System.out.println("UserManagerImpl.delUser()userId-->"+userId);
    }

    public String findUser(String userId, String userName) {
        // TODO Auto-generated method stub
        System.out.println("UserManagerImpl.findUser()userId-->"+userId);
        return userName ;
    }

    public void modifyUser(String userId, String userName) {
        // TODO Auto-generated method stub
        System.out.println("UserManagerImpl.modifyUser()userId-->"+userId);
    }

}
bubuko.com,布布扣
bubuko.com,布布扣
package com.javadesignpattern.Proxy.Dynamic;

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

public class LoggerHandler implements InvocationHandler{
    
    Object target;

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("begin time:" +getTime());
        try{
            Object result = method.invoke(target, args);
            System.out.println("success time:" +getTime());
        }catch(Exception e){
            e.printStackTrace();
            System.out.println("failed time:" +getTime());
        }
        return null;
    }
    
    public Object newInstance(Object target){
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }
    
    public String getTime(){
        SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateTime = tempDate.format(new java.util.Date());
        return dateTime;
    }

}
bubuko.com,布布扣
bubuko.com,布布扣
package com.javadesignpattern.Proxy.Dynamic;

public class Client {
    
    public static void main(String[] args){
        LoggerHandler loggerHandle = new LoggerHandler();
        UserManager userManager = (UserManager)loggerHandle.newInstance(new UserManagerImpl());
        userManager.addUser("001", "Christy");
    }

}
bubuko.com,布布扣

可以看到jdk的动态代理被代理的对象必须实现接口。好忧桑啊。解决的办法是我们想到spring的cglib实现的动态代理,cglib是针对类(实际上是继承子真实主题)的代理,但是不能代理final的(final的不能继承嘛~)。

---------动态代理的优点:

接口中声明的多有方法都被转移到调用处理器中一个集中的方法中进行处理(invocationhandle:invoke),这样接口数量比较多的时候,我们就可以灵活处理。这是优于静态代理的地方。

设计模式(就) : 结构型模式--代理模式,布布扣,bubuko.com

设计模式(就) : 结构型模式--代理模式

标签:des   c   style   class   blog   code   

原文地址:http://www.cnblogs.com/ChristyorRuth/p/3763459.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!