代理模式之静态代理、动态代理

代理模式,常用的一种设计模式。


优点:
1.Client端通过使用代理对象ProxySubject来间接的控制另外一个对象RealSubject,从而使Client端与具体实现类RealSubject解耦,扩展性更好;
2.Client端不用关心具体实现类RealSubject的方法实现,只需要关系代理对象中提供的方法;
3.代理ProxySubject也起到了控制安全访问的目的。

缺点:
1.由于增加了代理对象,所以有可能会造成请求的处理速度变慢;
2.实现代理模式需要额外的工作,相同的方法需要在代理对象与真实实现对象上都要实现一遍,增加了代码量,而且有些代理模式实现起来会更复杂;

注意事项:这里可能会觉得代理模式与装饰器模式差不多,但其实代理模式是为了控制访问真实对象RealSubject;而装饰器模式是为了增强真实对象RealSubject的功能。

看一下UML图:

preview

静态代理:

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


选择使用哪种代理模式,这个需要根据项目的实际情况来决定了。如果以上内容对你有帮助,请记得点赞三连~

猜你喜欢

转载自blog.csdn.net/qq_33539839/article/details/113560312