zoukankan      html  css  js  c++  java
  • 重构之字段改名 UML行为图 用例图 时序图&协作图 状态图&活动图 依恋情结

    简单的使用一下字段改名

    为什么使用字段改名:

    ​ 你在一个软件上做的工作越多,对这个软件的数据的理解就越深刻,你需要把这些理解融入到代码中。利用名字的解释作用,让代码更容易被理解。

    如何找到该变量的所有引用点

    1. 类的私有字段:

      ​ 直接修改该字段名称,那么所有引用这个变量的地方将会报红,我们就找到了类中这个字段的所有引用点,之后用新名称依次修改这些引用点。

      实战:

      ​ 这个日志切面类LogAop中的字段clazz和method分别表示被访问的类和被访问的方法。更合适的名称是visitClass, visitMethod或者executionClass和executionMethod。

    package cn.itcast.ssm.controller;
    
    import cn.itcast.ssm.domain.SysLog;
    import cn.itcast.ssm.service.ISysLogService;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.context.SecurityContext;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.HttpServletRequest;
    import java.lang.reflect.Method;
    import java.util.Date;
    
    @Component
    @Aspect
    public class LogAop {
    
        @Autowired
        private HttpServletRequest request;
    
        @Autowired
        private ISysLogService sysLogService;
    
        private Class<?> clazz; //被访问的类
        private Method method; //被访问的方法
        private Date visitTime;
    
        @Pointcut("execution(* cn.itcast.ssm.controller.*.* (..)) && !execution(* cn.itcast.ssm.controller.SysLogController.* (..))")
        public void pointCut(){}
    
    //    @Before("execution(* cn.itcast.ssm.controller.*.* (..)))")
        @Before("pointCut()")
        public void before(JoinPoint joinPoint) throws NoSuchMethodException {
            /*
                获取访问时间
             */
            visitTime = new Date();
    
            /*
                获取类字节码对象和方法对象
             */
            clazz = joinPoint.getTarget().getClass();
            String methodName = joinPoint.getSignature().getName();
            Object[] args = joinPoint.getArgs();
    
            if(args == null || args.length == 0){
                method = clazz.getMethod(methodName);
            }else{
                Class<?>[] argsClass = new Class<?>[args.length];
                for (int i = 0; i < args.length; i++) {
                    argsClass[i] = args[i].getClass();
                }
                method = clazz.getMethod(methodName, argsClass);
            }
        }
    
    //    @AfterReturning("execution(* cn.itcast.ssm.controller.*.* (..))")
        @AfterReturning("pointCut()")
        public void after() throws Exception {
            /*
                获取执行时间
             */
            Long executionTime = new Date().getTime() - visitTime.getTime();
            /*
                获取url
             */
            String url = null;
            RequestMapping clazzAnnotation = clazz.getAnnotation(RequestMapping.class);
            if(clazzAnnotation != null){
                String[] classPath = clazzAnnotation.value();
                RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class);
                if(methodAnnotation != null){
                    String[] methodPath = methodAnnotation.value();
                    url = classPath[0] + methodPath[0];
                }
            }
            /*
                获取ip
                    需要获取request对象
             */
            String ip = request.getRemoteAddr();
            /*
                获取用户名
             */
            SecurityContext context = SecurityContextHolder.getContext();
            User principal = (User) context.getAuthentication().getPrincipal();
            String username = principal.getUsername();
            /*
                获取方法
             */
            String methodName = "[类名]" + clazz.getName() + "[方法名]" + method.getName();
    
            //创建日志记录,并进行保存
            SysLog sysLog = new SysLog();
            sysLog.setVisitTime(visitTime);
            sysLog.setUsername(username);
            sysLog.setIp(ip);
            sysLog.setUrl(url);
            sysLog.setExecutionTime(executionTime);
            sysLog.setMethod(methodName);
    
            sysLogService.save(sysLog);
        }
    }
    
    
    -- 日志表
    CREATE TABLE sysLog(
      id VARCHAR2(32) default SYS_GUID() PRIMARY KEY,
      visitTime timestamp,
      username VARCHAR2(50),
      ip VARCHAR2(30),
      url VARCHAR2(50),
      executionTime int,
      method VARCHAR2(200)
    );
    

    依恋情结

    ​ 函数对某个类的兴趣高过对自己所处的类的兴趣(依恋之苦)。无数次经验里,我们看到某个函数为了计算某个值,从另一个对象那儿调用几乎半打的取值函数。

    ​ 疗法:使用移动函数(Move Method)把这个函数移到它该去的地方。有时候函数中只有一部分受这种依恋之苦,这时候应该使用提炼方法,把这一部分提炼到独立函数中,在使用移动函数(Move Method)把它们带去它们该去的地方。

    UML

    UML用户指南 第二部分对基本结构建模 第7章 图

    1. 结构图

    2. 行为图

      5种行为图: 用例图 时序图和协作图 状态图和活动图

      交互图

      时序图与协作图

      ​ 时序图:强调消息时间顺序。

      ​ 协作图:强调接收和发送消息的对象的结构组织。

      状态图与活动图

  • 相关阅读:
    关于C#中Environment.OSVersion判断操作系统及Win10上的问题
    C#各种数组直接的数据复制/转换
    移位操作<<和>>,是逻辑数字上的移动(和大端小端无关)
    log4net学习笔记
    链接错误——无法解析的外部符号 ConvertStringToBST
    当Thread.Sleep的暂停时间参数设置过小时,精度很差的解决方法
    Python发送邮件
    Python使用HTMLTestRunner运行所有用例并产生报告
    pandas学习笔记
    Python requests模块做接口测试
  • 原文地址:https://www.cnblogs.com/mozq/p/11096518.html
Copyright © 2011-2022 走看看