zoukankan      html  css  js  c++  java
  • 设计模式-代理模式

    模式定义

    给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用

    为什么使用代理

    在不改变目标对象方法的情况下对方法进行增强

    代理模式实例

    静态代理

    先创建一个用户接口(UserInterface),声明一个方法

    public interface UserInterface {
    
        void service(String s);
    }
    

    创建实现类(UserImpl)

    public class UserImpl implements UserInterface {
    
        @Override
        public void service(String s) {
            System.out.println("我是" + s);
        }
    }
    

    创建代理对象类(UserProxy),通过代理类创建实现类实例并访问其方法

    public class UserProxy implements UserInterface {
    
        private UserInterface user;
    
        public UserProxy(UserImpl user) {
            this.user = user;
        }
    
        @Override
        public void service(String s) {
            System.out.println("检查身份");
            user.service(s);
            System.out.println("请进门");
        }
    }
    

    客户端调用

    public class ProxyTest {
        public static void main(String[] args) {
            UserImpl user = new UserImpl();
            UserProxy proxy = new UserProxy(user);
            proxy.service("wupx");
        }
    }
    

    输出结果

    检查身份
    我是wupx
    请进门
    

    动态代理

    先创建一个User接口

    public interface User {
    
        void code();
    
        void sleep();
    }
    
    

    创建User的实现类(UserImpl)

    public class UserImpl implements User {
        @Override
        public void code() {
            System.out.println("开始敲代码");
        }
    
        @Override
        public void sleep() {
            System.out.println("开始睡觉");
        }
    }
    
    

    再创建一个代理类(UserImpProxy)

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class UserImpProxy implements InvocationHandler {
    
        private User user;
    
        public UserImpProxy(User user) {
            this.user = user;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            String methodName = method.getName();
            Object result;
            if ("code".equals(methodName)) {
                System.out.println("讨论需求");
                result = method.invoke(user, args);
                System.out.println("提测");
            } else if ("sleep".equals(methodName)) {
                System.out.println("洗澡");
                result = method.invoke(user, args);
            } else {
                result = method.invoke(user, args);
            }
            return result;
        }
    }
    

    去测试动态代理

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;
    
    public class TestProxy {
        public static void main(String[] args) {
            UserImpl user = new UserImpl();
            InvocationHandler userProxyHandler = new UserImpProxy(user);
            User userProxy = (User) Proxy.newProxyInstance(user.getClass().getClassLoader(),
                    user.getClass().getInterfaces(), userProxyHandler);
            userProxy.code();
            userProxy.sleep();
        }
    }
    
    

    运行结果

    讨论需求
    开始敲代码
    提测
    洗澡
    开始睡觉
    

    总结

    使用Java动态代理的两个重要步骤

    1. 通过实现 InvocationHandler 接口创建自己的调用处理器;
    2. 通过为Proxy类的newProxyInstance方法指定代理类的ClassLoader 对象和代理要实现的interface以及调用处理器InvocationHandler对象来创建动态代理类的对象;
  • 相关阅读:
    C#开发ActiveX控件并应用于网页
    C#编写ActiveX控件
    WPF Step By Step 系列5-Prism框架在项目中使用
    WPF Step By Step4- 自定义模板
    WPF Step By Step3- 控件介绍
    WPF Step By Step2 -基础知识介绍
    WPF Step By Step 系列1
    斑马打印机设定值取值优先级顺序
    WPF资料汇总
    linux(centos8):使用cgroups做资源限制
  • 原文地址:https://www.cnblogs.com/wupeixuan/p/11433903.html
Copyright © 2011-2022 走看看