1. 程式人生 > >結構型模式-代理模式

結構型模式-代理模式

  代理模式和裝飾器模式比較相似,都是對原有物件進行額外的操作,不同的是裝飾器是對原有物件的修飾,而代理模式是接手原物件的功能,並新增新的特性

  先來看靜態代理的例子,使用者管理

package constructional.pattern.proxy.staticproxy;
/***
 * 使用者控制介面
 * @author Administrator
 *
 */
public interface UserManager {

    public void addUser(String userId,String userName);
    public void modifyUser(String userId,String userName);
    
public void delUser(String userId); public String findUser(String userId); }
package constructional.pattern.proxy.staticproxy;

/****
 * 使用者管理真正的實現類
 * @author Administrator
 *
 */
public class UserManagerImpl implements UserManager {

    /*****
     * 新增使用者
     */
    public void addUser(String userId, String userName) {
            System.out.println(
"正在新增使用者,使用者為:"+userId+userName+"……"); } /***** * 刪除使用者 */ public void delUser(String userId) { System.out.println("delUser,userId="+userId); } /*** * 查詢使用者 */ public String findUser(String userId) { System.out.println("findUser,userId="+userId);
return userId; } public void modifyUser(String userId, String userName) { System.out.println("modifyUser,userId="+userId); } }
package constructional.pattern.proxy.staticproxy;

/***
 * 代理類,提供使用者實現類的訪問控制
 * @author Administrator
 *
 */
public class Proxy implements UserManager{
    private UserManager userManager;
    public Proxy(UserManagerImpl ul)
    {
        userManager=ul;
    }
    public void addUser(String userId, String userName) {
        System.out.println("正在進行新增使用者前的準備工作,使用者id為:"+userId+"……");
        try {
            userManager.addUser(userId, userName);
            System.out.println("成功新增使用者"+userId+",正在進行確認處理……");
        } catch (Exception e) {
            System.out.println("新增,userId="+userId+"失敗!");
        }
        
        
    }

    public void delUser(String userId) {
        // TODO Auto-generated method stub
        
    }

    public String findUser(String userId) {
        // TODO Auto-generated method stub
        return null;
    }

    public void modifyUser(String userId, String userName) {
        // TODO Auto-generated method stub
    }
}

  測試程式碼

package constructional.pattern.proxy.staticproxy;

/****
 * 客戶端
 * @author Administrator
 *
 */
public class Client {

        public static void main(String []args)
        {
            UserManager userManager=new Proxy( new UserManagerImpl());
            userManager.addUser("0001", "張三");
        }
}

  執行結果

  看完了靜態代理,再來看看動態代理,正常的動態代理

package constructional.pattern.proxy.dynamicproxy;

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

public class LoginHandler2 implements InvocationHandler {


    private Object target;
    
    public LoginHandler2(Object target) {
        super();
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("登入成功");
        try {
            method.invoke(target, null);
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

  

package constructional.pattern.proxy.dynamicproxy;

public class User implements UserMgr{

    @Override
    public void addUser() {
        System.out.println("新增使用者");
        
    }
}
package constructional.pattern.proxy.dynamicproxy;

public interface UserMgr {

    public void addUser();
}

  測試程式碼

package constructional.pattern.proxy.dynamicproxy;

import java.lang.reflect.Proxy;

public class JdkTest2 {
    public static void main(String args[]){
        User u = new User();
        LoginHandler2 l = new LoginHandler2(u);
        ClassLoader c = ClassLoader.getSystemClassLoader();
        try {
            UserMgr ur = (UserMgr)Proxy.newProxyInstance(c,new Class[]{UserMgr.class}, l);
            ur.addUser();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

  執行結果

  下面是手動編譯代理類的程式碼

package constructional.pattern.proxy.dynamicproxy;

import java.lang.reflect.Method;

public interface InvocationHandler {

    public void invoke(Object o,Method m);
}
package constructional.pattern.proxy.dynamicproxy;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class LoginHandler implements InvocationHandler{

    private Object target;
    
    public LoginHandler(Object target) {
        super();
        this.target = target;
    }

    @Override
    public void invoke(Object o, Method m) {
        System.out.println("登入成功");
        try {
            m.invoke(target, null);
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
package constructional.pattern.proxy.dynamicproxy;

public interface UserMgr {

    public void addUser();
}
package constructional.pattern.proxy.dynamicproxy;

public class User implements UserMgr{

    @Override
    public void addUser() {
        System.out.println("新增使用者");
        
    }
}
package constructional.pattern.proxy.dynamicproxy;

import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Random;

import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class Proxy {

    public static Object getProxyInstance(Class inface,InvocationHandler h) throws Exception{
        String rt ="\r\t";
        byte[] bytes = new byte[1];
        bytes[0] = 1;
        String className = "P" + Math.abs(new Random().nextLong());
        String methodStr = "";
//        for(Method m:inface.getMethods()){
//            methodStr+="    @Override" + rt+
//                        "    public void " + m.getName() + "(){" + rt +
//                        "            long startTime = System.currentTimeMillis();"+ rt +
//                        "            System.out.println(\"startTime:\"+startTime);"+ rt +
//                        "            t." + m.getName() + "()" + ";"+ rt +
//                        "            long endTime = System.currentTimeMillis();"+ rt +
//                        "            System.out.println(\"Time:\"+(endTime-startTime));"+ rt +
//
//                        "     }" + rt;
//
//        }
        for(Method m : inface.getMethods()) {
            methodStr += "@Override" + rt + 
                         "public void " + m.getName() + "() {" + rt +
                         "    try {" + rt +
                         "    Method md = " + inface.getName() + ".class.getMethod(\"" + m.getName() + "\");" + rt +
                         "    h.invoke(this, md);" + rt +
                         "    }catch(Exception e) {e.printStackTrace();}" + rt +
                        
                         "}";
        }

        
        
        String str = 
        
        "package constructional.pattern.proxy.dynamicproxy;"+ rt +
        "import java.lang.reflect.Method;" + rt +
        "public class " + className + "Proxy implements " +inface.getName()+ "{"+ rt +

        "   constructional.pattern.proxy.dynamicproxy.InvocationHandler h;" + rt +
            
            
        "    public " + className + "Proxy(InvocationHandler h) {"+ rt +
        "        super();"+ rt +
        "        this.h = h;"+ rt +
        "}"+ rt +

            methodStr+

        "}";
        String fileName =System.getProperty("user.dir")+"/src/constructional/pattern/proxy/dynamicproxy/" + className + "Proxy.java";
        FileWriter fw = new FileWriter(fileName);
        fw.write(str);
        fw.flush();
        fw.close();
        //compile
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);
        Iterable units = fileMgr.getJavaFileObjects(fileName);
        CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);
        t.call();
        fileMgr.close();
        
        //load into memory and create an instance
        URL[] urls = new URL[]{(new URL("file:/"+System.getProperty("user.dir")+"/src/"))};
        URLClassLoader ul = new URLClassLoader(urls);
        Class c = ul.loadClass("constructional.pattern.proxy.dynamicproxy." + className +"Proxy");
        System.out.println(c);
        Constructor ctr = c.getConstructor(InvocationHandler.class);
        Object m = (Object)ctr.newInstance(h);
        return m;
    }
}

  測試類

package constructional.pattern.proxy.dynamicproxy;

public class Test2 {

    public static void main(String args[]){
        User u = new User();
        LoginHandler l = new LoginHandler(u);
        try {
            UserMgr ur = (UserMgr)Proxy.getProxyInstance(UserMgr.class, l);
            ur.addUser();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
}

  執行結果