Stopwatch Class는 무슨일을 할까? 그리고 메소드 네이밍과 책임.

2020. 9. 3. 18:52 Spring Framework/Spring boot

앞서 SpringApplication Class를 보면서 run 메소드 안에 StopWatch라는 클래스를 본적이 있다. 클래스 명만 보고 그냥 StopWatch 기능을하는 클래스구나하고 넘어갔는데, 오늘 문뜩 그 클래스가 생각이나서 한번 봤는데 역시나다. (java-doc 문서)


SpringApplication 클래스에서 StopWatch에 사용되는 메소드는 start, stop 를 사용하고 객체를 StartupInfoLogger.logStarted 메소드에 파라미터로 넘긴다.


start

1
2
3
4
5
6
7
8
public void start(String taskName) throws IllegalStateException {
    if (this.running) {
        throw new IllegalStateException("Can't start StopWatch: it's already running");
    }
    this.running = true;
    this.currentTaskName = taskName;
    this.startTimeMillis = System.currentTimeMillis();
}
cs

  자바에서 기본으로 제공하는 System.currentTimeMillis 메소드로 시작 시간을 변수에 저장하는 것을 볼 수 있다.


stop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void stop() throws IllegalStateException {
    if (!this.running) {
        throw new IllegalStateException("Can't stop StopWatch: it's not running");
    }
    long lastTime = System.currentTimeMillis() - this.startTimeMillis;
    this.totalTimeMillis += lastTime;
    this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime);
    if (this.keepTaskList) {
        this.taskList.add(lastTaskInfo);
    }
    ++this.taskCount;
    this.running = false;
    this.currentTaskName = null;
}
cs

  단순하다 start에서 저장한 시작 시간과 stop 메소드가 호출된 시간을 계산해서 저장한다. task 설명은 생략(클래스 보면 자바 개발자라면 누구나 이해 할 수 있을 정도로 쉽다.)


메소드 네이밍과 책임

  사실 이 메소드를 보다가 메소드명을 보고 메소드명으로 책임을 어떻게 가져가야할까 문뜩 떠 오른 부분이 있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public String prettyPrint() {
    StringBuilder sb = new StringBuilder(shortSummary());
    sb.append('\n');
    if (!this.keepTaskList) {
        sb.append("No task info kept");
    }
    else {
        sb.append("-----------------------------------------\n");
        sb.append("ms     %     Task name\n");
        sb.append("-----------------------------------------\n");
        NumberFormat nf = NumberFormat.getNumberInstance();
        nf.setMinimumIntegerDigits(5);
        nf.setGroupingUsed(false);
        NumberFormat pf = NumberFormat.getPercentInstance();
        pf.setMinimumIntegerDigits(3);
        pf.setGroupingUsed(false);
        for (TaskInfo task : getTaskInfo()) {
            sb.append(nf.format(task.getTimeMillis())).append("  ");
            sb.append(pf.format(task.getTimeSeconds() / getTotalTimeSeconds())).append("  ");
            sb.append(task.getTaskName()).append("\n");
        }
    }
    return sb.toString();
}
cs

  StopWatch 클래스에 prettyPrint라는 메소드를 보고 문뜩 spring에서 controller test 코드 작성 시 사용했던 MockMvcResultHandlers.pinrt()가 생각났다. 단순히 메소드명에 print가 들어갔기 때문에 생각났다.

  print라는 단어가 들어간 메소드는 어떤 역할을 하고 있을지 궁금했기 때문이다. 위 코드를 보면 보다 시피 prettyPrint 메소드는 어디에도 데이터를 출력하는 부분이 없다. 그런데 MockMvcResultHandlers.print 메소드는(소스는 생략) 실제로 출력하는 책임도 담당하는데, print라는 단어가 포함된 메소드는 실제로 데이터를 출력하는게 맞는것인가 아니면 출력할 문자열을 반환하는게 맞는것인가? 정답은 모르겠다. 일단 고민거리 하나 던지고 마무리.

출처 : https://blog.woniper.net/310?category=699184