Java设计模式-Proxy代理模式

问题分析:

什么是代理模式呢?其实我们在生活中并不少见。对于程序员来说最常接触的莫过于代理上网了,连接大力服务器地址,就可以访问网络。

还有每天吃饭赶进度是常事,叫公司的同事帮忙带饭也是一种代理;如果你辞职老板不给你发工资,那么你还得请个律师帮你打官司,这也是一种代理。总之生活中无处不在。

代理的定义:

为其他对象提供一种代理以控制对这个对象的访问。简单点就是在不直接操作访问对象的的情况下,找一个代理访问该对象,就是自己不想搞,这个其他人帮你搞。

基本UML图:


具体问题UML类图:


抽象主题类Subject.java

package com.hust.staticProxy1;

public abstract class Subject {
     public abstract void visit();//普通业务方法
}
实现抽象主题的真正主题类RealSubject.java

package com.hust.staticProxy1;

public class RealSubject extends Subject {

	public void visit() {
		System.out.println("Real Subject!");

	}

}
代理类ProxySubject.java

package com.hust.staticProxy1;
//代理类
public class ProxySubject extends Subject {
    private  RealSubject mRealSubject;//把被代理对象作为成员变量
    public ProxySubject(RealSubject mRealSubject){
    	this.mRealSubject=mRealSubject;
    }
	public void visit() {
		mRealSubject.visit();//调用被代理对象的逻辑方法
	}

}
Client.java

package com.hust.staticProxy1;

public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		 //实例化一个被代理对象
		 RealSubject mRealSubject=new RealSubject();
		 //用被代理对象构造一个代理对象
		 ProxySubject mProxySubject=new ProxySubject(mRealSubject);
		 //调用代理对象的相关方法
		 mProxySubject.visit();
	}

}
代理模式的简单实现:
设定一个故事情节,小明上班遇到一个被老板拖欠工资甚至克扣工资的情况,这种情况下小明还是通过法律来解决问题,一旦小明选择走法律途径解决该纠纷,那么不可避免的需要请个律师作为自己的诉讼代理人,我们将诉讼流程抽象在一个接口中。

诉讼接口类

package com.hust.staticProxy2;

public interface LawSuit {
	  //提交申请
     void submit();
     //进行举证
     void burden();
     //开始辩护
     void defend();
     //诉讼完成
     void finish();
}
具体诉讼人,就是被代理对象小明,就是他想做的事

package com.hust.staticProxy2;

public class XiaoMing implements LawSuit {//被代理类,实现诉讼接口

	public void submit() {
		// 老板欠小明工资,小明只好申请仲裁
		System.out.println("老板欠小明工资,小明只好申请仲裁");

	}

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

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

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

}
代理律师类:就是代理对象,小明让这个代理类完成诉讼流程

package com.hust.staticProxy2;
//律师代理类
public class Lawyer implements LawSuit{
	private LawSuit mLawSuit;
	
	public Lawyer(LawSuit mLawSuit){
		this.mLawSuit=mLawSuit;
	}
	public void submit() {
		// 调用被代理类的方法
		mLawSuit.submit();
	}

	public void burden() {
		// 调用被代理类的方法
		mLawSuit.burden();
	}

	public void defend() {
		// 调用被代理类的方法
		mLawSuit.defend();
	}

	public void finish() {
		// 调用被代理类的方法
		mLawSuit.finish();
	}

}
客户端类

package com.hust.staticProxy2;

public class ClientTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
	    //构造被代理对象小明
		LawSuit xiaoming=new XiaoMing();
		//小明委托代理对象律师
		Lawyer mLawyer=new Lawyer(xiaoming);
		//代理对象律师帮助小明提出诉讼申请
		mLawyer.submit();
		//代理对象律师进行举证
		mLawyer.burden();
		//代理对象律师代替小明进行辩护
		mLawyer.defend();
		//代理对象律师完成诉讼
		mLawyer.finish();

	}

}
输出:

老板欠小明工资,小明只好申请仲裁
这是合同书和过去一年的银行卡工资流水
证据确凿!不需要早说些什么了!
诉讼成功,判决老板即日起七天内结算工资

代理模式的意义:
代理模式到底好处在哪里呢??
那先要说一下代理模式中的三种角色了。
   抽象角色:声明真实对象和代理对象的共同接口。
   代理角色代理对象角色内部含有对真实对象的引用, 从而可以操作 真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象,可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。

  真实角色代理角色所代表的真实对象,是我们最终要引用的对象

  代理模式的一个好处就是对外部提供统一的接口方法,而代理类在接口中实现对真实类的附加操作行为,从而可以在不影响外部调用情况下,进行系统扩展。也就是说,我要修改真实角色的操作的时候,尽量不要修改他,而是在外部在“包”一层进行附加行为,即代理类。例如:接口A有一个接口方法operator(),真实角色:RealA实现接口A,则必须实现接口方法operator()。客户端Client调用接口A的接方法operator()。现在新需求来了,需要修改RealA中的operator()的操作行为。怎么办呢?如果修改RealA就会影响原有系统的稳定性,还要重新测试。这是就需要代理类实现附加行为操作。创建代理ProxyA实现接口A,并将真实对象RealA注入进来。ProxyA实现接口方法operator(),另外还可以增加附加行为,然后调用真实对象的operator()。从而达到了“对修改关闭,对扩展开放”,保证了系统的稳定性。我们看客户端Client调用仍是接口A的接口方法operator(),只不过实例变为了ProxyA类了而已。也就是说代理模式实现了ocp原则。


什么时候使用代理模式
  当我们需要使用的对象很复杂或者需要很长时间去构造,这时就可以使用代理模式(Proxy)。例如:如果构建一个对象很耗费时间和计算机资源,代理模式(Proxy)允许我们控制这种情况,直到我们需要使用实际的对象。一个代理(Proxy)通常包含和将要使用的对象同样的方法,一旦开始使用这个对象,这些方法将通过代理(Proxy)传递给实际的对象。 一些可以使用代理模式(Proxy)的情况:
  1,一个对象,比如一幅很大的图像,需要载入的时间很长。    
     2,一个需要很长时间才可以完成的计算结果,并且需要在它计算过程中显示中间结果
  3,一个存在于远程计算机上的对象,需要通过网络载入这个远程对象则需要很长时间,特别是在网络传输高峰期。
  4,一个对象只有有限的访问权限,代理模式(Proxy)可以验证用户的权限


  代理模式(Proxy)也可以被用来区别一个对象实例的请求和实际的访问,例如:在程序初始化过程中可能建立多个对象,但并不都是马上使用,代理模式(Proxy)可以载入需要的真正的对象。这是一个需要载入和显示一幅很大的图像的程序,当程序启动时,就必须确定要显示的图像,但是实际的图像只能在完全载入后才可以显示!这时我们就可以使用代理模式(Proxy)。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值