代理模式,常用的一种设计模式。
优点:
1.Client端通过使用代理对象ProxySubject来间接的控制另外一个对象RealSubject,从而使Client端与具体实现类RealSubject解耦,扩展性更好;
2.Client端不用关心具体实现类RealSubject的方法实现,只需要关系代理对象中提供的方法;
3.代理ProxySubject也起到了控制安全访问的目的。
缺点:
1.由于增加了代理对象,所以有可能会造成请求的处理速度变慢;
2.实现代理模式需要额外的工作,相同的方法需要在代理对象与真实实现对象上都要实现一遍,增加了代码量,而且有些代理模式实现起来会更复杂;
注意事项:这里可能会觉得代理模式与装饰器模式差不多,但其实代理模式是为了控制访问真实对象RealSubject;而装饰器模式是为了增强真实对象RealSubject的功能。
看一下UML图:
静态代理:
1.创建一个Game接口
public interface Game{
void play(String gameName);
}
2.创建实现接口的实体类RealGame
public class RealGame implements Game{
@Override
public void play(String gameName) {
System.out.println("play " + gameName);
}
}
3.创建实现接口的代理类ProxyGame
public class ProxyGame implements Game{
private RealGame realGame;
public ProxyGame(){
realGame = new RealGame();
}
@Override
public void play(String gameName) {
realGame.play(gameName);
}
}
4.客户端Client使用代理类ProxyGame来获取RealGame类的对象
public class ProxyGameDemo {
public static void main(String[] args) {
Game game = new ProxyGame();
game.play("静态代理 game");
}
}
5. 执行程序,输出结果:
play 静态代理 game
动态代理:
1.创建一个Game接口
public interface Game{
void play(String gameName);
}
2.创建实现接口的实体类RealGame
public class RealGame implements Game{
@Override
public void play(String gameName) {
System.out.println("play " + gameName);
}
}
3.创建ProxyGameHandler实现InvocationHandler接口方法
public class ProxyGameHandler implements InvocationHandler {
protected Game game;
public ProxyGameHandler(Game game) {
this.game = game;
}
/**
*
* @param proxy 被代理的对象
* @param method 要调用被代理对象的方法
* @param args 方法调用时需要的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(game, args);
}
}
4.客户端Client使用代理类ProxyGame来获取RealGame类的对象
public class ProxyGameDemo {
public static void main(String[] args) {
RealGame realGame = new RealGame();
Game game = (Game) Proxy.newProxyInstance(
realGame.getClass().getClassLoader(), //被代理类的类加载器
realGame.getClass().getInterfaces(), //被代理类的接口方法
new ProxyGameHandler(realGame)); //拦截的方法在被拦截时需要执行哪个InvocationHandler的invoke方法
game.play("动态代理 game");
}
}
5. 执行程序,输出结果:
play 动态代理 game
选择使用哪种代理模式,这个需要根据项目的实际情况来决定了。如果以上内容对你有帮助,请记得点赞三连~