zoukankan      html  css  js  c++  java
  • 设计模式【代理模式】

           首先,让我们来了解代理商,它是指代理人或代理机构代表一个人与一个人或组织采取行动。

    代理模式用于特定的目的是提供一个代理对象,并由代理对象控制对象控制对原对象的引用。
           代理模式一般涉及三个角色:
           Subject:抽象角色。声明真实对象和代理对象的共同接口。
        Proxy:代理角色。代理对象角色内部含有对真实对象的引用。从而能够操作真实对象,同一时候代理对象鱼与真

    实对象同样的接口以便在不论什么时刻都能取代真实对象。

    同一时候,代理对象能够在运行真实对象操作时。附加其它的操作,相当于对真实对象进行封装。

    简言之,代理角色是业务逻辑的详细运行者。
        RealSubject:真实角色,代理角色所代表的真实对象,即我们终于要引用的对象。

    案例场景:
           客户Client,通过手机代理商MobileProxy(Proxy)购买(获取)一部手机(Mobile),而真实手机提供商是手机工厂MobileFactory(RealSubject)。

    【转载使用。请注明出处:http://blog.csdn.net/mahoking

    演示程序:

    /**
     * 物品商品对象
     * @author Mahc
     */
    public class Mobile {
    	public void call() {
    		System.out.println("Mobile[合格]能够打电话!");
    	}
    }
    
    /**
     * RealSubject
     * @author Mahc
    */
    public class MobileFactory implements Factory {
    
    @Override
    	public Mobile produce() {
    		return new Mobile();
    	}
    }
    
    /**
     * Subject 抽象对象
     * @author Mahc
     */
    public interface Factory {
    	public Mobile produce();
    }
    
    /**
     * Proxy对象
     * @author Mahc
     */
    public class MobileProxy implements Factory {
    
    	private MobileFactory factory;
    	
    	/**MobileProxy 构造函数*/
    	protected MobileProxy(MobileFactory mobileFactory) {	
    		this.factory = mobileFactory;
    	}
    
    	@Override
    	public Mobile produce() {
    		return factory.produce();
    	}
    }
    
    /**
     * 模拟客户对象
     * @author Mahc
     */
    public class Client {
    
    	public static void main(String[] args) {	
    		//真实的Mobile生产商
    		MobileFactory mobileFactory = new MobileFactory();
    		MobileProxy mobileProxy = new MobileProxy(mobileFactory);
    		//使用MobileProxy对象的produce()方法,生产Mobile
    		Mobile mobile = mobileProxy.produce();
    		mobile.call();
    	}
    }

           在此我们已经初步了解了设计模式中的代理模式。以下我们进一步了解代理模式中静态代理与动态代理的差别。
           静态代理(Static Proxy):真实对象和代理对象有共同的接口。 代理对象角色内部含有对真实对象的引用,从而能够操作
    真实对象,同一时候代理对象提供与真实对象同样的方法。
           动态代理(Dynamic Proxy):真实对象和抽象对象有共同的接口,代理对象角色通过Java的反射机制

    (java.lang.reflect.Method.newProxyIntance())获得,同一时候代理对象(为java.lang.reflect.InvocationHandler的子类通

    过invoke())调用真实对象同样的方法。

           所以从综上所看到的可知,第一个演示案例为静态代理模式。

    以下我们提供动态代理模式的案例。

    本例所涉及的新的知识点需要读者和本人在平时不断补充与积累。比如反射机制的思想与相关的Java API,假设学习深入会发现这方面的学习会触及AOP(面向切面编程)。

    动态代理案例:

    /**
     * 获取动态代理对象的类
     * @author Mahc
     *
     */
    public class ProxyHandler implements InvocationHandler{
    
    	private Object object;
    	
    	public ProxyHandler(Object object) {
    		this.object = object;
    	}
    
    	/**
    	 * 生成代理对象的静态方法
    	 * @param realObject
    	 * @return
    	 */
    	public static Object  getProxyIntance(Object realObject){
    		
    		Class<?> classType = realObject.getClass();
            return Proxy.newProxyInstance(classType.getClassLoader(), 
                    classType.getInterfaces(),  new ProxyHandler(realObject));
    	}
    
    	/**
    	 * proxy 代理对象
    	 * method 调用的方法
    	 * args 方法的參数
    	 */
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args)
    			throws Throwable {
    		if("produce".equalsIgnoreCase(method.getName())){
    			System.out.println("运行了Mobile.call()");
    		}
    		Object resultObj = method.invoke(object, args);
    //		System.out.println(resultObj.getClass());
    		return resultObj;
    	}
    
    }
    
    
    
    public class Client {
    
    	public static void main(String[] args) {
    		
    		MobileFactory mobileFactory = new MobileFactory();
    		Factory factory = (Factory) ProxyHandler.getProxyIntance(mobileFactory);
    		Mobile mobile = factory.produce();
    		mobile.call();
    	}
    }


     以下我们来对照两种代理模式的优缺点。
           静态代理:
           长处:
                  1、对象直观。静态代理是实实在在的存在的。我们创建编写。
                  2、在编译期增加,提前就指定好使用对象。所以效率高。
           缺点:
                  1、 代理对象与真实对象关联性高,所以须要代理多个真实对象时。须要大量的代理类。
                  2、 在编译期增加关联对象,系统的灵活性差。

    动态代理:
           长处:
                 1、一个动态代理类能够简单解决创建多个静态代理的麻烦。
                 2、调用目标代码时,会在方法“执行时”动态的增加。调用灵活。
           缺点:
                 1、系统灵活了,可是相比而言。效率减少了。比静态代理慢一点。
                 2、动态代理比静态代理在代码的可读性上差了一点,不太easy理解。


                 3、JDK动态代理仅仅能对实现了接口的类进行代理。(这个问题以下会介绍)

           静态代理VS动态代理,各自有各的独特之处,均不可取代,在项目中究竟使用哪种代理模式,须要依据自身的须要来定。

    以下我们来解释上面遗留的问题,以上我们介绍的这样的动态代理叫做jdk proxy即原生的jdk代理。它事实上也不是完美的。它仅仅能代理实现了接口的类如【MobileFactory implements Factory】,不能对类本身实现代理,要完毕对类本身实现代理。须要用到另外一个开源的类库cglib【CGLIB(Code Generation Library)】。还有待继续我们平时不断学习与研究

    【转载使用,请注明出处:http://blog.csdn.net/mahoking

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    NOIP前咕咕 : BZOJ3172: [Tjoi2013]单词
    BZOJ4350: 括号序列再战猪猪侠【区间DP】
    Codeforces 983B. XOR-pyramid【区间DP】
    POJ1651 Multiplication Puzzle【区间DP】
    LOJ10131. 「一本通 4.4 例 2」暗的连锁【树上差分】
    UOJ22. 【UR #1】外星人【DP】【思维】
    BZOJ5125: [Lydsy1712月赛]小Q的书架【决策单调性优化DP】【BIT】【莫队】【分治】
    Codeforces 868F. Yet Another Minimization Problem【决策单调性优化DP】【分治】【莫队】
    BZOJ1835: [ZJOI2010]base 基站选址【线段树优化DP】
    Codeforces 165 E. Compatible Numbers【子集前缀和】
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4633967.html
Copyright © 2011-2022 走看看