代理模式

定义

为其他对象提供一种代理以控制对这个对象的访问

普通代理

大家都知道玩游戏的时候有时候会找代练帮你升级啥的,下面用代码来实现这个过程

首先定义游戏玩家的接口,定义玩家的动作

1
2
3
4
5
public interface IGamePlayer {
void login(String user,String password);
void killBoss();
void upgrade();
}

现在定义真实玩家,构造函数约束了谁能创建角色以及传入用户名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class GamePlayer implements IGamePlayer {
private String name;

public GamePlayer(IGamePlayer _gamePlayer, String name) throws Exception {
if (_gamePlayer == null) {
throw new Exception("不能创建真实角色");
} else {
this.name = name;
}
}

@Override
public void login(String user, String password) {
System.out.println("登录名:"+user+"的用户"+this.name+"登录游戏");
}

@Override
public void killBoss() {
System.out.println(this.name+"在打怪");
}

@Override
public void upgrade() {
System.out.println(this.name+"升级了");
}
}

以下是代理来创建真实玩家

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class GamePlayerProxy implements IGamePlayer {
private IGamePlayer gamePlayer = null;

public GamePlayerProxy(String name) throws Exception {
this.gamePlayer = new GamePlayer(this,name);
}

@Override
public void login(String user, String password) {
this.gamePlayer.login(user,password);
}

@Override
public void killBoss() {
this.gamePlayer.killBoss();
}

@Override
public void upgrade() {
this.gamePlayer.upgrade();
}
}

以上就是普通代理,通过代理传入用户名即可实现真实玩家的打怪升级

1
2
3
4
5
6
7
8
@Test
public void testGamePlayerProxy() throws Exception{

IGamePlayer gamePlayer = new GamePlayerProxy("杰克");
gamePlayer.login("jack","123");
gamePlayer.killBoss();
gamePlayer.upgrade();
}

动态代理

我们经常听到的aop就是使用了动态代理,现在以开车为例实现动态代理

1
2
3
4
5
public interface IDriveCar {
void start();
void drive();
void stop();
}

下面定义实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class DriveCar implements IDriveCar {
private String name;

public DriveCar(String name) {
this.name = name;
}

@Override
public void start() {
System.out.println(this.name+"启动车子");
}

@Override
public void drive() {
System.out.println(this.name+"在开车");
}

@Override
public void stop() {
System.out.println(this.name+"停车达到");
}
}

现在定义一个实现了InvocationHandler(jdk)接口的实现类来处理带来方法的运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class DriveCarProxyHandler implements InvocationHandler {

Object obj=null;

public DriveCarProxyHandler(Object obj) {
this.obj = obj;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(this.obj,args);
if(method.getName().equalsIgnoreCase("start")){
System.out.println("有人开你的车");
}
return result;
}
}

测试,使用Proxy.newProxyInstance来生成代理对象:

1
2
3
4
5
6
7
8
9
10
11
@Test
public void testDriveCarProxy() throws Exception{

IDriveCar driveCar = new DriveCar("jack");
InvocationHandler handler = new DriveCarProxyHandler(driveCar);
ClassLoader loader = driveCar.getClass().getClassLoader();
IDriveCar proxy = (IDriveCar) Proxy.newProxyInstance(loader,driveCar.getClass().getInterfaces(),handler);
proxy.start();
proxy.drive();
proxy.stop();
}

动态代理一般实现方式

需要代理的类
1
2
3
public interface SubObject {
void doSomething(String str);
}

1
2
3
4
5
6
public class RealObject implements SubObject {
@Override
public void doSomething(String str) {
System.out.println("doSomething is :"+str);
}
}
方法处理以及代理
1
2
3
4
5
6
7
8
9
10
11
12
public class MyInvocationHandler implements InvocationHandler {

private Object target = null;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(this.target,args);
return result;
}
}

1
2
3
4
5
6
7
8
9
10
11
public class DynamicProxy <T>{

public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler){
if(true){
(new BeforeAdvice()).exec();
}
return (T) Proxy.newProxyInstance(loader,interfaces,handler);

}

}
比如方法前后插入执行的方法
1
2
3
public interface IAdvice {
void exec();
}

1
2
3
4
5
6
public class BeforeAdvice implements IAdvice {
@Override
public void exec() {
System.out.println("before advice");
}
}
对代理类进一步封装
1
2
3
4
5
6
7
8
public class SubjectDynamicProxy extends DynamicProxy {
public static <T> T newProxyInstance(SubObject subObject){
ClassLoader loader = subObject.getClass().getClassLoader();
Class<?>[] interfaces = subObject.getClass().getInterfaces();
InvocationHandler handler = new MyInvocationHandler(subObject);
return newProxyInstance(loader,interfaces,handler);
}
}
测试

封装前

1
2
3
4
5
6
7
8
@Test
public void testDynamic(){
SubObject subObject = new RealObject();
InvocationHandler handler = new MyInvocationHandler(subObject);
SubObject proxy = DynamicProxy.newProxyInstance(
subObject.getClass().getClassLoader(),RealObject.class.getInterfaces(),handler);
proxy.doSomething("listen song");
}

封装后

1
2
3
4
5
6
@Test
public void test01(){
SubObject subObject = new RealObject();
SubObject proxy = SubjectDynamicProxy.newProxyInstance(subObject);
proxy.doSomething("go go go ");
}