首先先来张UML图,代理模式用的最多的就是静态代理以及动态代理,掌握这两种差不多就可以啦,如果想更深入的了解就自己多看看其他学习资料。
静态代理
1.定义一个接口
public interface IGamePlayer {
void login(String user , String password);
void killBoss();
void upgrade();
}
2、实现这个接口
public class GamePlayer implements IGamePlayer {
private String name = "";
public GamePlayer(IGamePlayer igp, String name) {
this.name = name;
}
public GamePlayer(String name){
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 + " 又升了一级!");
}
}
3、ProxyModel类
<pre name="code" class="java">
public class ProxyModel implements IGamePlayer{
private IGamePlayer gamePlayer = null;
public ProxyModel(String name){
gamePlayer = new GamePlayer(this,name);
}
public ProxyModel(IGamePlayer gamePlayer){
this.gamePlayer = gamePlayer;
}
@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();
}
}
4、测试类
ProxyModel proxy = new ProxyModel("张三");
proxy.login("zhangsan", "password");
proxy.killBoss();
proxy.upgrade();
静态代理的实现很简单,但是也有其不足:一个代理类只能为一个接口服务,如果要代理的方法很多,那就必须为每一个方法进行代理,如果接口增加一个方法,不仅目标类要实现这个方法,而且代理类也要做相应的修改,代码的维护就会变的复杂很多,如果要代理不同的接口,那就需要实现多个代理类,使得代码的复用性很差.而动态代理则能够通过反射机制等实现一个代理类完成全部的代理功能,降低了代码间的耦合度和维护时的复杂度.
动态模式
动态代理常用的实现方式有JDK动态代理和cglib动态代理,JDK动态代理通过反射机制来实现代理功能,但只能代理实现了接口的类,而没有实现接口的类可以通过cglib来代理.cglib动态代理的原理是对目标类生成一个子类,并覆盖其中的方法,但是有final修饰的类由于不能继承故cglib不能进行代理.
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
*
* @author wghd
*/
public class GamePalyerIH implements InvocationHandler{
private Object target;
//绑定委托对象并返回一个代理类
public Object bind(Object target){
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
result = method.invoke(target, args);
return result;
}
}
测试类
GamePalyerIH proxy = new GamePalyerIH();
IGamePlayer igp = (IGamePlayer) proxy.bind(new GamePlayer("zhangnsan"));
igp.login("aa", "aa");
igp.killBoss();
igp.upgrade();