代理模式定义
代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式组成
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
代理模式结构图
代理分类
- 静态代理
- 动态代理
代码示例
静态代理
抽象角色定义如下:
/**
* Created by xujinping on 2018/3/22.
* 定义游戏接口
*/
public interface IGames {
/**
* 行走
*/
void work();
/**
* 射击
*/
void shoot();
}
真实角色实现如下:
/**
* Created by xujinping on 2018/3/22.
* 游戏的真实角色类
*/
public class Games implements IGames {
private static final String TAG = "Proxy";
@Override
public void work() {
Log.i(TAG, "真实角色 work: ");
}
@Override
public void shoot() {
Log.i(TAG, "真实角色 shoot: ");
}
}
代理角色定义如下:
/**
* Created by xujinping on 2018/3/22.
* 静态代理
*/
public class GameProxy implements IGames {
private static final String TAG = "Proxy";
private IGames mGames;
public GameProxy(IGames iGames) {
this.mGames = iGames;
}
@Override
public void work() {
//在真实角色执行方法之前加自己的逻辑
Log.e(TAG, "代理角色 work: start");
if (mGames != null) {
mGames.work();
}
//在真实角色执行方法之后加自己的逻辑
Log.e(TAG, "代理角色, work: end");
}
@Override
public void shoot() {
Log.e(TAG, "代理角色 shoot: start");
if (mGames != null) {
mGames.shoot();
}
Log.e(TAG, "代理角色, shoot: end");
}
}
使用如下:
IGames mRealRole;
IGames mProxyRole;
mRealRole = new Games();
mProxyRole = new GameProxy(mRealRole);
//执行真实角色
public void runRealRole(View view) {
mRealRole.work();
mRealRole.shoot();
}
//执行代理角色
public void runProxyRole(View view) {
mProxyRole.work();
mProxyRole.shoot();
}
打印如下:
动态代理
代码实现如下:
/**
* Created by xujinping on 2018/3/22.
* 动态代理
*/
public class DynamicGameProxy {
private static final String TAG = "Proxy";
private static class MyHandler implements InvocationHandler {
Object target;//真实角色,被代理对象
public MyHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Log.i(TAG, "动态代理 " + method.getName() + " start");
Object object = method.invoke(target, args);
Log.i(TAG, "动态代理 " + method.getName() + " end");
return object;
}
}
public static void test(IGames games) {
IGames game = (IGames) Proxy.newProxyInstance(games.getClass().getClassLoader(), games.getClass().getInterfaces(), new MyHandler(games));
game.work();
game.shoot();
}
}
打印如下:
总结
代理的优势:
- 容易扩展,比如在Games类中 在调用work方法之前添加新逻辑-穿鞋putOnShoes方法,我们可以不改动原有类的前提下来实现。
- 代理对象在客户端和真实目标对象起到中介和保护作用,也就是客户端不需要直接和真实目标对象接触。