设计模式–代理模式
一、静态代理:
本质:业务类和代理类都实现业务接口类,业务类实现业务逻辑处理,在代理类中通过业务类实例对象调用对应的业务逻辑方法
访问者只访问代理类,不会直接访问业务类
简单实例:
游戏类接口(业务类接口)
interface IGame(){
public void plays(String name);
}
普通玩家(业务类):
class GamePlayer implements IGame(){
@override
public void plays(String name){
System.out.printIn(name+"-->玩家玩游戏");
}
}
代练玩家(代理类):
class ProxyPlayer implements IGame(){
private IGame igame;
public ProxyPlayer(IGame _igame){
this.igame = _igame;
}
@override
public void plays(String name){
this.igame.plays(name)
}
}
测试:
class Test(){
public static void mian(String[] args){
IGame gamePlayer = new GamePlayer();
IGame proxyPlayer = new ProxyPlayer(gamePlayer):
proxyPlayer.plays("张三");
}
}
输出:
张三–>玩家玩游戏
缺点:
1、代理类和业务接口类耦合度太高,业务接口类增加、修改业务接口,代理类和业务类都需要一起修改
2、代理类的代码复用性不高,每个不同的业务接口类的重写业务接口都不能复用,代理接口越多,代理类越庞大
二、动态代理:
游戏类接口(业务类接口)
interface IGame(){
public void plays(String name);
}
普通玩家(业务类):
class GamePlayer implements IGame(){
@override
public void plays(String name){
System.out.printIn(name+"-->玩家玩游戏");
}
}
动态代理类:
class MyInvocationHandler implements InvocationHandler {
private Object subject;
public MyInvocationHandler(Object obj){
this.subject = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(subject,args);
}
}
测试:
class Test(){
public static void mian(String[] args){
IGame gamePlayer = new GamePlayer();
InvocationHandler handler = new MyInvocationHandler(gamePlayer);
IGamePlayer igp = (IGamePlayer)Proxy.newProxyInstance(gamePlayer.getClass().getClassLoader(), gamePlayer.getClass() .getInterfaces(), handler);
igp.plays("张三");
}
}
输出:
张三–>玩家玩游戏
动态代理核心:
1、JDK提供了InvocationHandler接口,通过实现该接口,重写invoke()方法,调用的是Object里的method,Object类适用于不同业务接口类
2、JDK提供了代理类Proxy,通过调用该类的newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法,生成代理类实例对象
loader : 类加载器
interfaces: 接口类所有抽象方法
h: handler
总结:InvocationHandler接口实现提供代理内容,Proxy代理类生成具体接口的具体代理
缺点:
只能对接口进行代理,不能对类进行代理
Spring AOP(面向切面编程) 就是用的代理模式