一:代理模式例子:
先附上代码:
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
动态代理---待学习