动态代理与设计思想

60 阅读1分钟

动态代理

把核心方法和其他琐碎的方法分开来执行

好处:解耦合,提高代码的维护

  1. 什么是动态代理?

    为目标对象,自动生成一个代理对象,代理对象可以做目标对象功能之外的事情,类似生活中的经纪人

  2. 多态代理是使用场景是什么?

    统计方法执行时间

  3. java哪个类可以实现动态代理?

    Proxy

public interface UserService {
    void login(String username,String password) throws InterruptedException;
    void deletuUser() throws InterruptedException;
    List<String> selectUsers() throws InterruptedException;
}
public class User implements UserService{
    private String userName;
    private String password;
    List<String> list;
​
    @Override
    public void login(String username, String password) throws InterruptedException {
        Thread.sleep(1000);
        if("root".equals(username)&&"12345".equals(password)){
           System.out.println("登录成功");
       }else {
           System.out.println("用户名或密码不对");
       }
​
    }
​
    @Override
    public void deletuUser() throws InterruptedException {
        Thread.sleep(4000);
        System.out.println("删除用户成功");
    }
​
    @Override
    public List<String> selectUsers() throws InterruptedException {
        Thread.sleep(3000);
        System.out.println("查询任务成功");
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张三","王五","赵四");
        return list;
    }
}
public class ProxyUtil {
    public static UserService getProxy(UserService userService){
        UserService us = (UserService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader()
                , new Class[]{UserService.class}, new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        String name = method.getName();
                        Object invoke = null;
                        if (name.equals("login") || name.equals("deletuUser") || name.equals("selectUsers")) {
                            long start = System.currentTimeMillis();
                            invoke = method.invoke(userService, args);
                            long end = System.currentTimeMillis();
                            System.out.println("方法执行了耗时(单位:毫秒)" + (end - start));
                        } else {
                            invoke = method.invoke(userService, args);
                        }
                        return invoke;
                    }
                });
             return us;
    }
}
public class Demo {
    public static void main(String[] args) throws InterruptedException {
        User user = new User();
//        user.login("root","12345");
//        user.deletuUser();
//        List<String> list = user.selectUsers();
//        System.out.println(list);
        UserService proxy = ProxyUtil.getProxy(user);
        proxy.login("root","12345");
        proxy.deletuUser();
        proxy.selectUsers();
    }
}

设计思想

Kiss保持代码的可读和维护简单易懂

面向接口编程

SOKID分为:

单一原则:指一个类负责完成一个职责或功能

开闭原则:重复的代码可以抽成方法或抽成抽象父类思考是否需要定义接口

里氏替换原则:子类覆写父类的方法后,不应该做不符合父类方法本意的事情

接口隔离原则:接口隔离原则指导我们在设计接口时应该保持接口的粒度小、高内聚、不耦合,避免定义大而全的接口。

依赖翻转原则:高层模块不要依赖低层模 块高层模块和低层模块应该通过抽象 互相依赖。