1.为什么要使用代理模式
http://www.cnblogs.com/silverLee/archive/2010/02/05/1664577.html
这篇文章举了几个很容易理解的例子,通俗点来讲就是,通过代理,你可以把一些复杂的步骤交给代理去做。就比如玩游戏的代练一样的,你自己可以在游戏里面聊天,交友,但是升级打怪可以交给代理模式。
2.先上一波类图(静态代理)
3.代理模式的实现
public interface IGamePlayer {
void killBoss();
void upGrade();
}
public class GamePlayer implements IGamePlayer{
private String name;
public void setName(String name) {
this.name = name;
}
@Override
public void killBoss() {
System.out.println(this.name + " kill Boss");
}
@Override
public void upGrade() {
System.out.println(this.name + " upGrade");
}
}
public class GameProxy implements IGamePlayer{
//给谁代理
private IGamePlayer gamePlayer;
public GameProxy(IGamePlayer gamePlayer){
this.gamePlayer = gamePlayer;
}
@Override
public void killBoss() {
//代理模式中可以增加预处理
System.out.println("//GameProxy kill Boss");
this.gamePlayer.killBoss();
}
@Override
public void upGrade() {
System.out.println("//GameProxy upGrade");
this.gamePlayer.upGrade();
}
}
main方法
public class Main {
public static void main(String[] args) {
GamePlayer gamePlayer = new GamePlayer();
gamePlayer.setName("Hr");
GameProxy gameProxy = new GameProxy(gamePlayer);//给这个对象进行代理
gameProxy.killBoss();//直接使用代理去打怪
gameProxy.upGrade();
}
}
//输出结果
//GameProxy kill Boss
Hr kill Boss
//GameProxy upGrade
Hr upGrade
//去掉注释的部分,就像是自己在打怪升级一样
//是不是可以联想到spring的AOP,可以在方法执行时进行一些额外的操作
//事实上spring的AOP就是代理,只不过是动态代理
上面只是最简单的静态代理,接下来介绍强制代理。在静态代理中,我们仍然可以自己去打怪升级而不依靠代理,但是在强制代理中,我们就必须使用代理去进行打怪升级
4.强制代理的类图
还是这些类,只不过接口多了个获取代理的方法,真正实体类持有代理实体类的对象。
5.强制代理的实现
public interface IGamePlayer {
void killBoss();
void upGrade();
IGamePlayer getProxy();
}
public class GamePlayer implements IGamePlayer{
private String name;
private IGamePlayer proxy;//持有代理类的实例
public GamePlayer(String name){
this.name = name;
}
@Override
public IGamePlayer getProxy(){
this.proxy = new GameProxy(this);
return this.proxy;
}
@Override
public void killBoss() {
if(!isProxy()){
throw new RuntimeException("请使用代理进行操作!");
}
System.out.println(this.name + " kill boss");
}
@Override
public void upGrade() {
if(!isProxy()){
throw new RuntimeException("请使用代理进行操作!");
}
System.out.println(this.name + " upGrade");
}
private boolean isProxy(){
return !(null == this.proxy);
}
}
public class GameProxy implements IGamePlayer{
private IGamePlayer gamePlayer;
public GameProxy(IGamePlayer gamePlayer){
this.gamePlayer = gamePlayer;
}
@Override
public void killBoss() {
this.gamePlayer.killBoss();
}
@Override
public void upGrade() {
this.gamePlayer.upGrade();
}
//代理的代理
@Override
public IGamePlayer getProxy() {
return this;
}
}
main方法
public static void main(String[] args) {
//失败,因为没有用代理
/*
IGamePlayer gamePlayer = new GamePlayer("HR");
gamePlayer.killBoss();
gamePlayer.upGrade();
*/
//失败,因为代理是new 出来的
/*
IGamePlayer gamePlayer = new GamePlayer("HR");
IGamePlayer gameProxy = new GameProxy(gamePlayer);
gameProxy.killBoss();
gamePlayer.upGrade();
*/
//成功
IGamePlayer gamePlayer = new GamePlayer("HR");
IGamePlayer proxy = gamePlayer.getProxy();
proxy.killBoss();
proxy.upGrade();
}
这种强制代理增加了复杂度,不过保证了代理的使用,实际项目中其实应该使用普通代理,并且约定不能不使用代理。
除了强制代理之外,还有动态代理模式。动态代理就是运行时代理,没有显示的代理类,但是可以利用反射、JDK的特性进行代理。
6.动态代理类图
其中GamePlayIH可以看作是代理类
7.动态代理的实现
public interface IGamePlayer {
void killBoss();
void upGrade();
}
public class GamePlayer implements IGamePlayer{
@Override
public void killBoss() {
System.out.println("kill boss");
}
@Override
public void upGrade() {
System.out.println("upGrade");
}
}
/**
* InvocationHandler是JDK提供的
*/
public class GamePlayIH implements InvocationHandler{
//被代理的实例
IGamePlayer gamePlayer;
public GamePlayIH(IGamePlayer obj){
this.gamePlayer = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("this is in invoke");
return method.invoke(this.gamePlayer, args);
}
}
main方法
/**
* 动态代理
*/
public class Main {
public static void main(String[] args) {
IGamePlayer gamePlayer = new GamePlayer();
InvocationHandler gameHandler = new GamePlayIH(gamePlayer);
ClassLoader classLoader = gamePlayer.getClass().getClassLoader();
//动态生成一个代理者
IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(classLoader, gamePlayer.getClass().getInterfaces(), gameHandler);
proxy.killBoss();
proxy.upGrade();
}
}
//输出结果
this is in invoke
kill boss
this is in invoke
upGrade