结构型设计模式之代理模式

原创 2017年10月06日 11:49:41

代理模式的介绍

代理模式(Proxy Pattern)也称为委托模式,属于结构型设计模式。其实不少设计模式中都有代理模式的影子,那么何为代理呢?
其实代理在我们日常生活中并不少见,对于程序员来说莫过于代理上网了,连上代理服务器地址,就可以轻松畅游全世界的网络,还有每天吃饭时赶进度是常事,叫朋友帮忙买饭也是一种代理。总而言之,也许你并不留意,但是代理的确是无处不在的,现实生活中如此,我们的Code世界里也是如此!

代理模式的定义

为其他对象提供一种代理以控制对这个对象的访问

代理模式的使用场景

当无法或不想直接访问某个对象存在困难时就可以通过一个代理对象来间接访问,为了保证客户端使用的透明度,委托对象与代理对象必须实现相同的接口

代理模式的简单实现

举一个生活中的例子,小李以前在公司上班时,就遇到被老板拖欠工资甚至克扣工资的情况,这种情况下,小李还是通过法律途径来解决问题,一旦小李选择了走法律途径解决该纠纷,那么不可避免地就需要请一个律师来作为自己的诉讼代理人,我们将诉讼流程抽象在一个接口类中。

//诉讼接口类
public interface ILawsuit{
//提交申请
void submit();
//进行举证
void burden();
//开始辩护
void defend();
//诉讼完成
void finish();
}

4个方法非常简单,都是诉讼的一般流程。

//具体诉讼人
public class XiaoLi implements ILawsuit{
@Override
public void submit(){
//老板欠小李工资 小李只好申请仲裁
System.out.println("老板拖欠工资!特此申请仲裁");
}

@Override
public void burden(){
//小李证据充足,不怕告不赢
System.out.println("这是合同书和过去一年的银行工资流水!");
}

@Override
public void defend(){
//铁证如山,辩护也没什么好说的
System.out.println("证据确凿!不需要再说什么了");
}

@Override
public void finish(){
//结果也是肯定的,必赢
System.out.println("诉讼成功!判决老板即日起七天内结算工资");
  }
}  

如上所诉,该类实现ILawsuit并对其中4个方法做出具体的实现逻辑,逻辑很简单,都只是输出一段话而已,当然,小李自己是不会去打官司的,于是小李请个律师代替自己进行诉讼。

//代理律师
public class Lawyer implements ILawsuit {
private ILawsuit mLawsuit;//持有一个具体被代理者的引用

public Lawyer(ILawsuit lawsuit){
mLawsuit=lawsuit;
}

@Override
public void submit(){
mLawsuit.submit;
}

@Override
public void burden(){
mLawsuit.burden;
}

@Override
public void defend(){
mLawsuit.defend;
}


@Override
public void finish(){
mLawsuit.finish;
  }
}

律师类表示代理者律师,在该类里面会持有一个被代理者(这里也就是上面的Aige类)的引用,律师所执行的方法实质上就是简单调用被代理者中的方法,下面来看看客户类中具体的调用执行关系。

//客户类
public class Client{
public static void main(String[] args){
//构造一个小李...
ILawsuit xiaoli = new XiaoLi();
//构造一个代理律师并将小李作为构造参数传递进去
ILawsuit lawyer = new Lawyer(xiaoli);
//律师提交申请
 lawyer.submit();
//律师进行举证
lawyer.burden();
//律师开始辩护
lawyer.defend();
//律师诉讼完成
lawyer.finish();
   }
}   

运行结果很简单这里不再给出,大家可以看到,其实代理模式也很简单,其主要还是一种委托机制,真实对象将方法的执行委托给代理对象,而且委托的干净利索毫不做作,这也是为什么代理模式也称为委托模式的原因,相信大家不难理解。除此之外还可以继续发散思维,其实我们的代理完全可以代理多个被代理类,就想上面的例子一样,一个律师可以代理多个人打官司,这是没有任何问题的,而具体到底是代理哪个人,这就要看代理类中所持有的实际对象类型,上述的例子中实际对象类型是XiaoLi,也就是代理的XiaoLi。

那么在此提出一个问题代理其他人可以吗?
答案是可以的,比如小明,我们只需要在定义XiaoMin类实现ILawsuit即可,再在客户端修改高层模块的调用逻辑,完全没有问题。


代理模式可以大致分为两部分,一是静态代理,二是动态代理。静态代理如上述示例那样,代理者的代码由程序员自己或通过一些自动化工具生成固定的代码再对其进行编译,也就是说在我们代码运行前代理类的class编译文件就已经存在了;而动态代理则与静态代理相反,通过反射机制动态地生成代理者的对象,也就是说我们在code阶段压根就不需要知道代理是谁,代理谁我们将会在执行阶段决定。而Java也给我们提供了一个便捷的动态代理接口InvocationHandler,实现该接口需要重写其调用方法invoke.

//动态代理类
public class DynamicProxy implements InvocationHandler{
private Object obj; //被代理的类引用

public DynamicProxy(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
//调用被代理类对象的方法
Object result=method.invoke(obj,args);
return result;
  }
}  

从上代码所述,我们声明一个Object的引用,该引用将指向被代理类,而我们调用被代理类的具体方法则在invoke方法中执行,是不是很简洁? 也就是说我们原来由代理类所做的工作现在由InvocationHandler来处理,不再需要关心到底代理谁。下面我们修改客户类的逻辑。

//修改好的客户类
public class Client{
public static void main(String[] args){
//构造一个小李
ILawsuit xiaoli=new XiaoLi();
//构造一个动态代理
DynamicProxy proxy = new DynamicProxy(xiaoli);
//获取被代理类小李的ClassLoader
classLoader loader=xiaoli.getClass().getClassLoader();
//动态构造一个代理者律师
ILawsuit lawyer=(ILawsuit) Proxy.newProxyInstance(loader,new Class[] {ILawsuit.class},proxy);
//律师提交申请
 lawyer.submit();
//律师进行举证
lawyer.burden();
//律师开始辩护
lawyer.defend();
//律师诉讼完成
lawyer.finish();
}
}

运行结果与之前一致,不再给出。由此可见动态代理可以通过一个代理类来代理N多个被代理类,其实质是对代理者与被代理者进行解耦,使两者直接没有直接的耦合关系。相对于静态代理则只能为给定接口下的实现类做代理,如果接口不同就需要重新定义不同地代理类,较为复杂,但是静态代理更符合面向对象原则。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

java设计模式--代理模式(结构型)

java设计模式--代理模式

"围观"设计模式(12)--结构型之代理模式(Proxy Pattern)

维基百科 代理模式(英语:Proxy Pattern)是程序设计中的一种设计模式。 所谓的代理者是指一个类可以作为其它东西的接口。代理者可以作任何东西的接口:网络连接、内存中的大对象、文件或其它昂贵或...

设计模式(十一)代理模式Proxy(结构型)

1.概述        因为某个对象消耗太多资源,而且你的代码并不是每个逻辑路径都需要此对象, 你曾有过延迟创建对象的想法吗 ( if和else就是不同的两条逻辑路径) ? 你有想过限制访问某个...

设计模式(十一)代理模式Proxy(结构型)

转载:http://blog.csdn.net/hguisu/article/details/7542143 设计模式(十一)代理模式Proxy(结构型) 1.概述        因为...

设计模式-结构型之代理模式

模式动机 在某些时候,有些对象出于权限、安全等各方面的因素不想直接被用户访问,此时需要通过设置一个“代理”对象作为第三者来实现间接访问。代理对象在客户端和目标对象中起到一个中介作用,并且通过代...

结构型:设计模式之代理模式(九)

代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口。根据代理模式...

设计模式(十一)代理模式Proxy(结构型)

本文转载自:http://blog.csdn.net/hguisu/article/details/7542143 1.概述        因为某个对象消耗太多资源,而且你的代码并不是每个逻辑路...

设计模式(结构型)之代理模式(Proxy Pattern)

代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口。根据代理模式...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)