zoukankan      html  css  js  c++  java
  • Java设计模式菜鸟系列(十四)代理模式建模与实现

    转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39856435


    代理模式(Proxy):代理模式事实上就是多一个代理类出来,替原对象进行一些操作。比方咱有的时候打官司须要请律师,由于律师在法律方面有专长,能够替咱进行操作表达咱的想法,这就是代理的意思。代理模式分为两类:1、静态代理(不使用jdk里面的方法);2、动态代理(使用jdk里面的InvocationHandler和Proxy)。以下请看演示样例:

    一、静态代理

    1、uml建模:



    2、代码实现

    /**
     * 演示样例(一):代理模式 --静态代理(没有调用JDK里面的方法)
     * 
     * 目标接口
     */
    
    interface Targetable {
    	public void targetMethod();
    }
    
    class Target implements Targetable {
    
    	@Override
    	public void targetMethod() {
    		System.out.println("this is a target method...");
    	}
    }
    
    class Proxy implements Targetable {
    	private Target target;
    
    	public Proxy() {
    		this.target = new Target();
    	}
    
    	private void beforeMethod() {
    		System.out.println("this is a method before proxy...");
    	}
    
    	private void afterMethod() {
    		System.out.println("this is a method after proxy...");
    	}
    
    	/**
    	 * 在运行目标方法前后加了逻辑
    	 */
    	@Override
    	public void targetMethod() {
    		beforeMethod();
    		target.targetMethod();
    		afterMethod();
    	}
    }
    
    /**
     * client測试类
     * 
     * @author Leo
     */
    public class Test {
    	public static void main(String[] args) {
    		/**
    		 * 创建代理对象
    		 */
    		Targetable proxy = new Proxy();
    		/**
    		 * 运行代理方法
    		 */
    		proxy.targetMethod();
    	}
    }
    

    二、动态代理

    1、uml建模:



    2、代码实现

    /**
     * 演示样例(二):代理模式 --动态代理
     * 
     * 以加入用户为例
     */
    class User {
    	private String username;
    	private String password;
    
    	public User() {
    	}
    
    	public User(String username, String password) {
    		this.username = username;
    		this.password = password;
    	}
    
    	public String getUsername() {
    		return username;
    	}
    
    	public void setUsername(String username) {
    		this.username = username;
    	}
    
    	public String getPassword() {
    		return password;
    	}
    
    	public void setPassword(String password) {
    		this.password = password;
    	}
    
    	@Override
    	public String toString() {
    		return "User [username=" + username + ", password=" + password + "]";
    	}
    }
    
    /**
     * 目标接口
     */
    interface IUserDao {
    	public void add(User user);
    }
    
    class UserDaoImpl implements IUserDao {
    	@Override
    	public void add(User user) {
    		System.out.println("add a user successfully...");
    	}
    }
    
    /**
     * 日志类 --> 待织入的Log类
     */
    class LogEmbed implements InvocationHandler {
    	private IUserDao target;
    
    	/**
    	 * 对target进行封装
    	 */
    	public IUserDao getTarget() {
    		return target;
    	}
    
    	public void setTarget(IUserDao target) {
    		this.target = target;
    	}
    
    	private void beforeMethod() {
    		System.out.println("add start...");
    	}
    
    	private void afterMethod() {
    		System.out.println("add end...");
    	}
    
    	/**
    	 * 这里用到了反射
    	 * 
    	 * proxy 代理对象
    	 * 
    	 * method 目标方法
    	 * 
    	 * args 目标方法里面參数列表
    	 */
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args)
    			throws Throwable {
    		beforeMethod();
    		// 回调目标对象的方法
    		method.invoke(target, args);
    		System.out.println("LogEmbed --invoke-> method = " + method.getName());
    		afterMethod();
    		return null;
    	}
    }
    
    /**
     * client測试类
     * 
     * @author Leo
     */
    public class Test {
    	public static void main(String[] args) {
    		IUserDao userDao = new UserDaoImpl();
    		LogEmbed log = new LogEmbed();
    		log.setTarget(userDao);
    		/**
    		 * 依据实现的接口产生代理
    		 */
    		IUserDao userDaoProxy = (IUserDao) Proxy.newProxyInstance(userDao
    				.getClass().getClassLoader(), userDao.getClass()
    				.getInterfaces(), log);
    		/**
    		 * 注意:这里在调用IUserDao接口里的add方法时,
    		 * 代理对象会帮我们调用实现了InvocationHandler接口的LogEmbed类的invoke方法。
    		 * 
    		 * 这样做,是不是有点像Spring里面的拦截器呢?
    		 */
    		userDaoProxy.add(new User("张三", "123"));
    	}
    }

    三、总结

    代理模式优点:1、一个代理类调用原有的方法,且对产生的结果进行控制。2、能够将功能划分的更加清晰,有助于后期维护。


  • 相关阅读:
    java中检测-在运行时指定对象是否是特定类的一个实例---关键字 instanceof
    关于Filter中ServletRequest和ServletResponse强转HttpServletRequest和HttpServletResponse
    jsp内置对象
    blender使用快捷键
    react-native学习笔记四====》配置路由(react-navigation4.x)
    react-native学习笔记三====》调试工具配置(chorm+react-devtools)
    react-native学习笔记二====》配置路由(react-navigation3.x)
    react-native学习笔记一====》环境搭建(填坑)
    vue表格打印
    学习资源
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4029045.html
Copyright © 2011-2022 走看看