代理模式

最近在看《设计模式之禅》复盘一下代理模式。

代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问。

一  简单例子

一个普通的代理模式的例子:

假如小明是一个正常的上班族,突然有一点他不想上班了,但是还是想领工资(我也想),这个时候他找了一个人每天帮他刷卡上班,工作,然后刷卡下班,然后工资还是小明领。。。

在这种情景下,我们给出一个普通代理模式的例子:

//代理模式 模拟正常上下班
public interface IWorker {

	//上班签到
	public void signIn (String user);
	
	//疯狂工作
	public  void work();
	
	//下班签退
	public void signOut(String user);
}



public class Worker implements IWorker {

	private  String user = "";
	
	public Worker(String user){
		this.user = user;
	}
	
	@Override
	public void signIn(String user) {
        System.out.println("用户:" + this.user + "刚刚签到...");
	}

	@Override
	public void work() {
		 System.out.println(this.user + "工作中...");
	}

	@Override
	public void signOut(String user) {
		 System.out.println("用户:" + user + "刚刚签退...");
	}

}



public class WorkerProxy implements IWorker {

	private IWorker worker = null;
	
	//通过构造函数传递进来一个需要代理的对象,也就是代替哪个人上班
	public WorkerProxy(IWorker iWorker){
		this.worker = iWorker;
	}
	
	//代替别人上班签到
	@Override
	public void signIn(String user) {
		this.worker.signIn(user);
	}
   
	//代替别人上班干活累成狗
	@Override
	public void work() {
        this.worker.work();
	}

	//代替别人下班签退
	@Override
	public void signOut(String user) {

		this.worker.signOut(user);
	}

}


public class testMain {

	public static void main(String[] args) {

		String user = "小明";
		// 小明是一个正常上班族
		Worker worker = new Worker(user);
		// 这个是小明找的代替他上班的人  代理
		WorkerProxy proxy = new WorkerProxy(worker);
		System.out.println("一天开始:...");
		//代理开始干活了...
		proxy.signIn(user);
		proxy.work();
		proxy.signOut(user);
		System.out.println("一天结束...");
	}

}

我们用一个接口模拟,小明上班、工作、下班的过程,给出两个实体类,分别作为真实类和接口类,调用方式如testMain类的显示,结果如下:

一天开始:...
用户:小明刚刚签到...
小明工作中...
用户:小明刚刚签退...
一天结束...

可以看出,代理人完美帮助小明上班,除了领工资、、、

二 代理模式扩展

2.1 普通代理

普通代理,要求就是客户端只能访问代理角色,而不能访问真实角色,继续上面小明的例子我们改造一个代码,如下:

//代理模式 模拟正常上下班
/**
 * 首先说普通代理,它的要求就是客户端只能访问代理角色,而不能访问真实角色,这是
 * 比较简单的。我们以上面的例子作为扩展
 */
public interface IWorker {

	//上班签到
	public void signIn (String user);
	
	//疯狂工作
	public  void work();
	
	//下班签退
	public void signOut(String user);
}



public class Worker implements IWorker {

	private String user = "";
	//构造函数限制谁能创建对象,并同时传递姓名
	public Worker(IWorker iworker, String user) throws Exception{
		if(iworker == null){
			throw new Exception("传入代理角色失败!");
		}else{
			this.user = user;
		}
	}
	
	@Override
	public void signIn(String user) {
        System.out.println("用户:" + this.user + "刚刚签到...");
	}

	@Override
	public void work() {
		 System.out.println(this.user + "工作中...");
	}

	@Override
	public void signOut(String user) {
		 System.out.println("用户:" + user + "刚刚签退...");
	}

}



public class WorkerProxy implements IWorker {
	
	private Worker worker;
	//通过构造函数传递要代替哪个兄弟上班,传递个名字过来
	public WorkerProxy(String user) throws Exception{
		worker = new Worker(this, user);
	}

	@Override
	public void signIn(String user) {

		this.worker.signIn(user);
	}

	@Override
	public void work() {

		this.worker.work();
	}

	@Override
	public void signOut(String user) {

		this.worker.signOut(user);
	}

}



public class testMain2_1 {

	public static void main(String[] args) throws Exception {

		String user = "小明";
		//给出一个代理人
		IWorker proxy = new WorkerProxy(user);
		System.out.println("一天开始:...");
		//代理开始干活了...
		proxy.signIn(user);
		proxy.work();
		proxy.signOut(user);
		System.out.println("一天结束...");
	}

}

可以看出,在testMain2_1中看不到Worker类了,只有代理类,也就是说只能访问代理类,使得外层对真实类屏蔽,测试结果如上。

2.2 强制代理

一般的思维都是通过代理找到真实的类,但是强制代理却是要“强制”通过真实角色查找到代理角色,否则不能访问。

还是小明的例子,代码如下:

/**
 * 你必须通过真实角色查找到代理角色,否则你不能访
 * 问。甭管你是通过代理类还是通过直接new一个主题角色类,都不能访问,只有通过真实角
 * 色指定的代理类才可以访问,也就是说由真实角色管理代理角色。
 */
public interface IWorker {

	//上班签到
	public void signIn (String user);
	
	//疯狂工作
	public  void work();
	
	//下班签退
	public void signOut(String user);
	
	//获取代理类 
	public IWorker getProxy();
}



public class Worker implements IWorker {
	
	private String user = "";
	//定义一个我需要调用的代理
	private IWorker proxy = null;
	
	public Worker(String user){
		this.user = user;
	}
	
	//找到自己的代理类
	@Override
	public IWorker getProxy(){
		this.proxy = new WorkerProxy(this);
		return this.proxy;
	}

	@Override
	public void signIn(String user) {

		if(this.isExistProxy()){
			 System.out.println("用户:" + this.user + "刚刚签到...");
		}else{
			System.out.println("请使用指定的代理访问");
		}
	}

	@Override
	public void work() {

		if(this.isExistProxy()){
			System.out.println(this.user + "工作中...");
		}else{
			System.out.println("请使用指定的代理访问");
		}
	}

	@Override
	public void signOut(String user) {
		if(this.isExistProxy()){
			System.out.println("用户:" + user + "刚刚签退...");
		}else{
			System.out.println("请使用指定的代理访问");
		}
	}

	private  boolean isExistProxy(){
		if(this.proxy == null){
			return false;
		}else{
			return true;
		}
	}
}



public class WorkerProxy implements IWorker {

	private IWorker iworker = null;

	//构造函数传递真实类(小明)
	public WorkerProxy(IWorker iworker) {
		this.iworker = iworker;
	}

	//代理上班签到
	@Override
	public void signIn(String user) {

		this.iworker.signIn(user);
	}

	//代理进行工作
	@Override
	public void work() {

		this.iworker.work();
	}

	//代理下班签退
	@Override
	public void signOut(String user) {

		this.iworker.signOut(user);
	}

	// 代理的代理暂时还没有,就是自己
	@Override
	public IWorker getProxy() {
		return this;
	}

}



public class testMain2_2 {

	public static void main(String[] args) {

		String user = "小明";
		
		//给出一个正常上班族
		IWorker worker = new Worker(user);
		//再给出一个代理人
		IWorker proxy = worker.getProxy();
		System.out.println("一天开始:...");
		//代理开始干活了...
		proxy.signIn(user);
		proxy.work();
		proxy.signOut(user);
		System.out.println("一天结束...");
	}

}

结果如上,强制代理的概念就是要从真实角色查找到代理角色,不允许直接访问真实角色。外层只要调用getProxy就可以访问真实角色的所有方法,它根本就不需要产生一个代理出来,代理的管理已经由真实角色自己完成

 

参考文献《设计模式之禅》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值