优点:屏蔽对真实对象的直接访问。
缺点:由于请求要经过代理,请求速度相应变慢。
以NBA为例子,比A球员想去湖人队打球,但是他又不想亲自去谈判各种琐碎的事情,这时候,经纪人就有他的作用了,交给经纪人去谈判,谈合适了就去打球就好了,而经纪人的工作就是一种代理模式。
代理模式主要分为静态代理和动态代理。
例子从简,经纪人和球员必须有一个共同的接口,包含谈判和打球方法,经纪人谈判好了通知球员去打球。
静态代理
创建一个NBA接口
/**
* 这是一个NBA接口
* negotiation 谈判方法
* playBasketball 打篮球方法
*/
public interface NBA {
void negotiation();
void playBasketball();
}
创建一个球员类并实现NBA接口
/**
* 这是一个球员类
*/
public class Player implements NBA {
@Override
public void negotiation() {
Log.d("TAG", "球员谈判");
}
@Override
public void playBasketball() {
Log.d("TAG", "球员打球");
}
}
创建一个代理类并实现NBA接口
/**
* 这是一个代理类
*/
public class NbaProxy implements NBA {
private NBA nba;
public NbaProxy(NBA nba) {
this.nba = nba;
}
@Override
public void negotiation() {
Log.d("TAG", "代理谈判");
}
@Override
public void playBasketball() {
//由于代理不会打球,执行球员打球方法。
nba.playBasketball();
}
}
调用:
/**
* 这是调用者
*/
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建球员
NBA player = new Player();
//创建代理
NBA proxy = new NbaProxy(player);
proxy.negotiation();
proxy.playBasketball();
}
}
结果:
image.png
就这样可以让球员不想自己处理的方法交给代理去处理,只需要干好自己的专业打球就行了。
动态代理(JDK自带动态代理)
比静态代理方便,不需再自己定义代理类,交给工具自动生成,主要交给两个类。
java.lang.reflect.Proxy:动态生成代理类对象。
java.lang.reflect.InvocationHandler(处理器接口):提供invoke方法对真实对象访问,每次通过Proxy生成代理类对象时都要指定对应的处理器对象。
创建一个球员类并实现NBA接口
/**
* 这是一个球员类
*/
public class Player implements NBA {
@Override
public void negotiation() {
Log.d("TAG", "球员谈判");
}
@Override
public void playBasketball() {
Log.d("TAG", "球员打球");
}
}
创建一个类直接实现InvocationHandler接口
/**
* 这是一个处理器接口
*/
public class NbaHandler implements InvocationHandler {
//NBA球员对象
private NBA nbaPlayer;
//通过构造器把NBA球员对象传进来
public NbaHandler(NBA nbaPlayer) {
this.nbaPlayer = nbaPlayer;
}
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
//核心方法,流程控制可在这处理
Object obj = null;
if (method.getName().equals("playBasketball")) {
//如果调用是打球方法球员去打
obj = method.invoke(nbaPlayer, args);
} else {
//如果调用谈判方法,就直接代理做
Log.d("TAG", "代理谈判");
}
return obj;
}
}
调用:
/**
* 这是调用者
*/
/**
* 这是调用者
*/
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建球员对象
NBA player = new Player();
//把对象交给处理器接口
NbaHandler nbaHandler = new NbaHandler(player);
//通过Proxy类生成代理对象
NBA proxy = (NBA) Proxy.newProxyInstance(MainActivity.class.getClassLoader(), new Class[]{NBA.class}, nbaHandler);
proxy.negotiation();
proxy.playBasketball();
}
}
结果:
image.png
已完成测试!有不对的地方欢迎指出,感恩。
网友评论