重构之字段改名 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种行为图: 用例图 时序图和协作图 状态图和活动图

    交互图

    时序图与协作图

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

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

    状态图与活动图

posted @ 2019-06-27 13:48  没有理由不会呀  阅读(238)  评论(0编辑  收藏  举报