zoukankan      html  css  js  c++  java
  • 设计模式学习--------12.代理模式学习

    场景:

         福尔摩斯一直想送礼物给花生,可是羞于直接赠送,于是想到让房东太太去帮忙送礼物.编程怎样实现呢?

    定义:

          为其它对象提供一种代理以控制对这个对象的訪问。

    角色:

    Proxy:代理对象.有下列功能:

    实现与详细的目标对象一样的接口,这样就能够使用代理来取代详细的目标对象。

    持有一个详细目标对象的引用,能够在须要时调用详细的目标对象。

    能够控制对目标对象的訪问,并能够负责创建和删除它。

    package com.kris.study;
    
    public class Proxy implements Subject {
    
    	private RealSubject realSubject = null;
    	
    	public Proxy(RealSubject realSubject){
    		this.realSubject = realSubject;
    	}
    	
    	@Override
    	public void request() {
    		System.out.println("代理之前做一些操作。。。。。。");
    		realSubject.request();
    		System.out.println("代理之后做一些操作。

    。。。

    。"); } }


    Subject:目标接口

    package com.kris.study;
    
    public interface Subject {
        public void request();
    }
    

    RealSubject:详细的目标对象,被代理的对象
    package com.kris.study;
    
    public class RealSubject implements Subject {
    
    	@Override
    	public void request() {
           //运行详细的功能处理
    	}
    
    }
    

    以下用代理模式实现场景。

    package com.kris.study;
    
    public interface SendGift {
        public void send();
    }
    

    package com.kris.study;
    
    public class Holmes implements SendGift {
    
    	@Override
    	public void send() {
    		System.out.println("送礼物给花生---来自福尔摩斯");
    	}
    
    }
    

    package com.kris.study;
    
    public class FangDongTaiTai implements SendGift {
    
    	private Holmes holmes = null;
    	
    	public FangDongTaiTai(Holmes holmes){
    		this.holmes = holmes;
    	}
    
    	@Override
    	public void send() {
    		System.out.println("亲爱的花生,老福让我给你带个东西");
    		holmes.send();
    	}
    	
    }
    

    package com.kris.study;
    
    public class Client {
       public static void main(String[] args) {
    	   Holmes holmes = new Holmes();
    	   SendGift sendGift = new FangDongTaiTai(holmes);
    	   sendGift.send();
       }
    }
    

    上面讲的都是静态代理,JAVA中提供了一套动态代理的机制,更加灵活。眼下JAVA的动态代理仅仅支持接口,若要实现类的代理,能够使用cglib.

    步骤:

    1.  创建一个实现接口InvocationHandler的类,它必须实现invoke方法。

    2.  创建被代理的类以及接口

    3.  通过Proxy的静态方法new ProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)

    创建一个代理,这个代理不管运行什么方法都会转到Handler中的invoke方法去调用.

    4.  通过代理调用方法


    上面第一步中的invoke方法參数说明

    pubilc Object invoke(Object obj,Method method,Object[] args)

    obj:代理类

    method:被代理的方法

    args:方法的參数


    动态代理实现场景:

    上面的SendGift接口和Holmes类都没变化,如今把房东太太的实现变更为实现InvocationHandler

    package com.kris.study;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class FangDongTaiTai implements InvocationHandler {
    
    	private SendGift holmes = null;
    	
    	public SendGift bindObject(Holmes holmes){
    		this.holmes = holmes;
    		SendGift sendProxy = (SendGift) Proxy.newProxyInstance(holmes.getClass().getClassLoader(),
    				holmes.getClass().getInterfaces(), this);
    		return sendProxy;
    	}
    
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args)
    			throws Throwable {
    		System.out.println("亲爱的花生,这是大福给你的");
    		return method.invoke(holmes, args);
    	}
    	
    
    	
    }
    

    package com.kris.study;
    
    public class Client {
       public static void main(String[] args) {
    	   Holmes holmes = new Holmes();
    	   FangDongTaiTai giftSendHandler = new FangDongTaiTai();
    	   SendGift proxy = giftSendHandler.bindObject(holmes);
    	   proxy.send();
       }
    }
    

    思考:

    代理模式的本质:控制对象的訪问

    特点:

    远程代理:Android中的Binder机制就是通过代理实现,本地通过一个代理对象去调用远程Service的方法。

    虚代理:比方载入数据库中全部人员数据,页面上仅仅显示人员名字,点击名字能够查看人员详细信息,这样先用代理对象载入全部人员的名字和ID.当真正须要看其它详细信息时,用代理对象再次去数据库载入全部人员数据。

    保护代理:对目标对象的訪问进行权限的管控,在代理对象中须要满足某种条件才干调用目标对象的方法。

    智能指引:在代理方法的前后运行一些附加的业务逻辑。AOP切面。


    何时使用代理:

    1.须要为一个对象在不同的地址空间提供局部代表的时候,能够使用远程代理

    2.须要创建开销非常大的对象时。能够使用虚代理。

    3.须要控制对原始对象的訪问的时候。能够使用保护代理

    4.须要在訪问对象运行一些附加操作的时候。能够使用智能指引代理


查看全文
  • 相关阅读:
    Ubuntu1804 安装 cuda 、cudnn、TensorRT
    sudo apt install nvinfer*
    PyTorch for Jetson Nano
    Jetson Nano安装 Jupyter lab
    docker容器登录,退出等操作命令
    pyenv和pipenv简单使用
    pyenv使用国内镜像安装指定的Python版本
    python写入csv文件的几种方法总结
    Python 能做什么?
    极验滑块验证的使用
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10470735.html
  • Copyright © 2011-2022 走看看