2014/7/19 代理模式

一:代理模式例子:

先附上代码:

IGamePlayer.java

package gamePlayer;

//游戏者
public class GamePlayer implements IGamePlayer {

	private String name = "";
	
	public GamePlayer(String _name)
	{
		this.name = _name;
	}
	
	public void killBoss() {
		// TODO Auto-generated method stub
		System.out.println(this.name+"在打怪");
	}

	public void login(String user, String password) {
		// TODO Auto-generated method stub
		System.out.println("登录名为"+user+"的用户"+this.name+"登录成功!");
	}

	public void upgrade() {
		// TODO Auto-generated method stub
		System.out.println(this.name+"又升了一级");
	}

}

GamePlayer.java

package gamePlayer;

//游戏者接口
public interface IGamePlayer 
{
	public void login(String user,String password);
	public void killBoss();
	public void upgrade();
}


GamePlayerProxy.java

package gamePlayer;

public class GamePlayerProxy implements IGamePlayer
{
    private IGamePlayer gamePlayer = null;
	
    //构造函数:对_gamePlayer对象进行代理
    public GamePlayerProxy(IGamePlayer _gamePlayer)
    {
    	this.gamePlayer = _gamePlayer;
    }
    
	public void killBoss() {
		// TODO Auto-generated method stub
		this.gamePlayer.killBoss();
	}

	public void login(String user, String password) {
		// TODO Auto-generated method stub
		this.gamePlayer.login(user, password);
	}

	public void upgrade() {
		// TODO Auto-generated method stub
		this.gamePlayer.upgrade();
	}

}

Client.java

package gamePlayer;

public class Client
{
	public static void main(String[] args)
	{
		IGamePlayer player = new GamePlayer("张三");
		//代练者
		IGamePlayer proxy = new GamePlayerProxy(player);
		
	    System.out.println("开始时间是"+System.currentTimeMillis());
	    proxy.login("zhangsan", "password");
	    proxy.killBoss();
	    proxy.upgrade();
	    System.out.println("结束时间是"+System.currentTimeMillis());
	    
	}
}

二:代理模式定义:

代理模式也称为委托模式

通用类图中有三个角色:

1.Subject抽象主题角色:抽象主题类可以是抽象类或接口

2.RealSubject具体主题角色:即被代理(委托)角色

3.Proxy代理主题角色:代理(委托)类

通用源码如下:

Subject.java

package proxyPattern;

public interface Subject
{
	public void request();
}

RealSubject.java

package proxyPattern;

public class RealSubject implements Subject
{
    //具体实现方法
	public void request() 
	{
		//业务逻辑处理
	}

}

Proxy:

package proxyPattern;

public class Proxy implements Subject
{
	//要代理哪个实现类
	private Subject subject = null; 

	//默认被代理者
	public Proxy()
	{
		this.subject = new Proxy();
	}
	
	//构造函数:传递被代理者
	public Proxy(Object object)
	{
		
	}
	
	//实现接口中定义的方法
	public void request() 
	{
		this.before();
		this.subject.request();
		this.after();
	}
	
	//预处理
	public void before()
	{
		//do something
	}
	
	//善后处理
	public void after()
	{
		//do something
	}

}

三:代理模式扩展:

普通代理:需要知道代理的存在

                  客户端只能访问代理角色,不能访问真实角色

强制代理:直接调用真实角色,不用关心代理是否存在


附上普通代理的代码:

IGamePlayer.java

package normalProxy;

public interface IGamePlayer 
{
	public void login(String user,String password);
	public void killBoss();
	public void upgrade();
}

GamePlayer.java

package normalProxy;

public class GamePlayer implements IGamePlayer
{
	private String name = "";//游戏者的名字
	
	//构造函数中新增IGamePlayer对象参数,限制只能对IGamePlayer对象进行代理
	public GamePlayer(IGamePlayer _gamePlayer,String name) throws Exception
	{
		if(_gamePlayer == null)
			throw new Exception("不能创建真实角色");
		else 
			this.name = name;
	}
	
	public void killBoss() {
		// TODO Auto-generated method stub
		System.out.println(this.name+"在打怪");
	}

	public void login(String user, String password) {
		// TODO Auto-generated method stub
		System.out.println("登录名为"+user+"的用户"+this.name+"登录成功!");
	}

	public void upgrade() {
		// TODO Auto-generated method stub
		System.out.println(this.name+"又升了一级");
	}

}

GamePlayerProxy.java

package normalProxy;

public class GamePlayerProxy implements IGamePlayer
{
	private IGamePlayer gamePlayer = null;
	
	//构造函数中仅仅传递一个被代理者的名称,而不是被代理者对象
	public GamePlayerProxy(String name)
	{
		try
		{
			gamePlayer = new GamePlayer(this,name);
		}
		catch(Exception e)
		{
			//异常处理
		}
	}

	public void killBoss() {
		// TODO Auto-generated method stub
		this.gamePlayer.killBoss();
	}

	public void login(String user, String password) {
		// TODO Auto-generated method stub
		this.gamePlayer.login(user, password);
	}

	public void upgrade() {
		// TODO Auto-generated method stub
		this.gamePlayer.upgrade();
	}
}

Client.java

package normalProxy;

public class Client
{
    public static void main(String[] args)
    {
        //代理者定义
        IGamePlayer proxy = new GamePlayerProxy("张三");
        
        System.out.println("开始时间是"+System.currentTimeMillis());
        proxy.login("zhangsan", "password");
        proxy.killBoss();
        proxy.upgrade();
        System.out.println("结束时间是"+System.currentTimeMillis());
    }
}

与第一个例子进行比较:

因为普通代理的客户端只能访问代理角色即GamePlayerProxy对象,不能访问真实对象即GamePlayer对象,所以场景类就不能new一个GamePlayer对象,必须由GamePlayerProxy来模拟,类图需要进行修改查阅书p119。

具体改动只有两处:

1.GamePlayer.java中的GamePlayer构造函数的参数中新增IGamePlayer对象,这样子限制了只有IGamePlayer对象能创建对象

2.GamePlayerProxy.java中的构造函数传递的不再是被代理者对象,只是被代理者的名字

这样做达到的目的:Client.java中调用者只需知道代理存在即可不用知道代理了谁


附上强制代理的代码:

IGamePlayer.java

package forcedProxy;

public interface IGamePlayer 
{
	public void login(String user,String password);
	public void killBoss();
	public void upgrade();
	//新增方法:找到自己的代理
	public IGamePlayer getProxy();
}

GamePlayer.java

package forcedProxy;

public class GamePlayer implements IGamePlayer
{
    private String name = "";
    
    //代理对象
    private IGamePlayer proxy = null;
    
    public GamePlayer(String _name)
    {
    	this.name = _name;
    }
    
    //找自己代理的方法
    public IGamePlayer getProxy()
    {
    	this.proxy = new GamePlayerProxy(this);
    	return this.proxy;
    }
    
    //检查是否是代理访问
    private boolean isProxy()
    {
    	if(this.proxy == null)
    		return false;
    	else 
    		return true;
    }


	public void killBoss() {
		// TODO Auto-generated method stub
		if(this.isProxy())
			System.out.println(this.name+"在打怪");
		else
			System.out.println("请使用指定的代理访问");
	}

	public void login(String user, String password) {
		// TODO Auto-generated method stub
		if(this.isProxy())
			System.out.println("登录名为"+user+"的用户"+this.name+"登录成功!");
		else
			System.out.println("请使用指定的代理访问");
	}

	public void upgrade() {
		// TODO Auto-generated method stub
		if(this.isProxy())
			System.out.println(this.name+"又升了一级");
		else
			System.out.println("请使用指定的代理访问");
	}

}

GamePlayerProxy.java

package forcedProxy;

public class GamePlayerProxy implements IGamePlayer
{
	private IGamePlayer gamePlayer = null;
	
	public GamePlayerProxy(IGamePlayer _gamePlayer)
	{
		this.gamePlayer = _gamePlayer;
	}

	//代理者的代理暂时为自己
	public IGamePlayer getProxy() {
		// TODO Auto-generated method stub
		return this;
	}

	public void killBoss() {
		// TODO Auto-generated method stub
		this.gamePlayer.killBoss();
	}

	public void login(String user, String password) {
		// TODO Auto-generated method stub
		this.gamePlayer.login(user, password);
	}

	public void upgrade() {
		// TODO Auto-generated method stub
		this.gamePlayer.upgrade();
	}

}

Client.java

package forcedProxy;

public class Client 
{
	public static void main(String[] args)
	{
		//直接访问真实角色
		IGamePlayer player = new GamePlayer("张三");
		System.out.println("开始时间是"+System.currentTimeMillis());
		player.login("zhangsan", "password");
		player.killBoss();
		player.upgrade();
		System.out.println("结束时间是"+System.currentTimeMillis());
	}
}
运行结果:

开始时间是1405758472489
请使用指定的代理访问
请使用指定的代理访问
请使用指定的代理访问
结束时间是1405758472489

出错原因:只能通过代理访问,直接访问没有用

public class Client 
{
	public static void main(String[] args)
	{	
		//直接访问代理类
		IGamePlayer player = new GamePlayer("张三");
		//定义一个代理者
		IGamePlayer proxy = new GamePlayerProxy(player);
		System.out.println("开始时间是"+System.currentTimeMillis());
		player.login("zhangsan", "password");
		player.killBoss();
		player.upgrade();
		System.out.println("结束时间是"+System.currentTimeMillis());
	}
}
运行结果:

开始时间是1405758730654
请使用指定的代理访问
请使用指定的代理访问
请使用指定的代理访问
结束时间是1405758730664

出错原因:不是player指定的代理者,而是自己new出来的

public class Client 
{
	public static void main(String[] args)
	{
                //强制代理的场景类
                IGamePlayer player = new GamePlayer("张三");
		IGamePlayer proxy = player.getProxy();
		System.out.println("开始时间是"+System.currentTimeMillis());
		player.login("zhangsan", "password");
		player.killBoss();
		player.upgrade();
		System.out.println("结束时间是"+System.currentTimeMillis());
	}
}
运行结果:

开始时间是1405759233924
登录名为zhangsan的用户张三登录成功!
张三在打怪
张三又升了一级
结束时间是1405759233924

动态代理---待学习


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值