设计模式(6)-代理模式详解(易懂)

2018-02-27 11:20:51来源:https://www.jianshu.com/p/0a3df5ad8e5c作者:安卓干货铺人点击

分享


代理模式定义

定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。




image

Subject:抽象角色,提取的公共方法,可以是一个接口或者抽象类


RealSubject:真实角色,实现具体的业务逻辑


Proxy:代理角色,对真实角色的逻辑处理,实现抽象角色的方法,并可以加上自己的操作逻辑。



实例说明

代理也就是委托,我首先想到的就是游戏代练。这个大家熟悉吧,下面就拿游戏代练来说明一下代理模式:


1.抽象角色:也就是公共方法-玩游戏刷级



public interface AbstractPlayer {
//玩游戏-刷级
public void playGame();
}

2.真实角色:这里指的是玩游戏的人



public class GamePlayer implements AbstractPlayer {
private String name="";
public GamePlayer(String name){
this.name=name;
}
@Override
public void playGame() {
Log.e("qzs","玩游戏-刷级");
}
}

3.代理,这里找个游戏代练来帮他刷级



public class Proxy implements AbstractPlayer {
private GamePlayer gamePlayer=null;
public Proxy(GamePlayer gamePlayer){
this.gamePlayer=gamePlayer;
}
@Override
public void playGame() {
this.gamePlayer.playGame();
}
}

4.调用:


       //新建一个游戏者
GamePlayer gamePlayer=new GamePlayer("秦子帅");
//定义一个代练者
Proxy proxy=new Proxy(gamePlayer);
//玩游戏刷级
proxy.playGame();



image

模式结构

代理模式分为静态代理、动态代理。


静态代理是由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。


动态代理是在实现阶段不用关心代理类,而在运行阶段才指定哪一个对象。


静态代理最基本的就是上面的实例了,下面主要讲解一下动态代理,这很重要。


动态代理

动态代理是在实现阶段不用关心代理类,而在运行阶段才指定哪一个对象。


首先先了解一下动态代理类


1.Interface InvocationHandler:


该接口中仅定义了一个方法Object:invoke(Object obj,Method method,Object[] args)。这个抽象方法在代理类中动态实现。


我们来看一下invoke中的三个参数:


obj一般是指代理类


method是被代理的方法


args为该方法的参数数组。


2.Proxy:


动态代理类,提供了getProxyClass (ClassLoader loader,Class[] interfaces)和newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)两种静态方法。


我们来看一下newProxyInstance中的三个参数:


CLassLoader loader:类的加载器


Class<?> interfaces:指定动态代理类需要实现的所有接口


InvocationHandler h:得到InvocationHandler接口的子类的实例


还拿上面的实例说:


1.建立动态代理类:


public class DynamicProxy implements InvocationHandler {
//对真实对象的引用-被代理的实例对象
private Object obj;
public DynamicProxy(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
Object result;
//可以加上调用方法之前的操作
result= method.invoke(this.obj,args);
//可以加上调用方法之后的操作
return result;
}
}

2.调用:



//新建一个游戏者
AbstractPlayer abstractPlayer=new GamePlayer("秦子帅");
InvocationHandler invocationHandler=new DynamicProxy(abstractPlayer);
//类加载器
ClassLoader classLoader=abstractPlayer.getClass().getClassLoader();
//动态产生一个代理者
AbstractPlayer proxy= (AbstractPlayer) Proxy.newProxyInstance(classLoader,new Class[]{AbstractPlayer.class},invocationHandler);
proxy.playGame();



image

注意:实现动态代理的首要条件:被代理类必须实现接口。


还有一些没有提出来,比如强制代理等等,这些大家可以自己去写一写...


文章学习参考了《设计模式之禅》与网上博文
另外可以加入我的Android技术交流群:458739310
大家可以关注我的微信公众号:「安卓干货铺」一个有质量、有态度的公众号!












最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台