본문 바로가기
golang

[golang] decorate 패턴을 사용하여 timer 구축하기(golang 시간 차이 구하기)

by devjh 2022. 2. 28.
반응형

이번 게시글에서는 golang에서 decorator 패턴을 사용하여 timer를 구축하는 방법에 대해 정리합니다.

 

1. 시간차이 구하기

package main

import (
   "fmt"
   "time"
)

func main() {
   startTime := time.Now()
   
   for i := 0; i < 10; i++ {
      fmt.Println("test")
   }
   
   // Sub 는 time 구조체로 생성된 객체에서 접근할 수 있습니다.
   // 현재시간을 측정하여 이전시간과의 차이를 직접 계산하는 방법입니다.
   endTime := time.Now()
   sub := endTime.Sub(startTime)
   fmt.Println(sub)

   // Since 는 현재시간 객체를 만들지 않아도 시간차이를 구할 수 있습니다.
   // startTime 시점과 현재시간의 차이가 양수로 출력됩니다.
   since := time.Since(startTime)
   fmt.Println(since)

   // Until 은 Since 와 사용방법은 동일합니다.
   // 현재시점과 startTime 차이가 음수로 출력됩니다.
   until := time.Until(startTime)
   fmt.Println(until)
}

golang이 time format이 워낙 괴랄하기도 하고 ("2006-01-02 15:04:05"는 "yyyy-mm-dd hh:mm:ss" 를 의미합니다....)

시간차이를 구하는 방법도 여러방식이 있으니 먼저 간단히 정리합니다.

 

time 패키지에는 시간차이를 구하는 Sub라는 메서드가 존재하며

 

해당 메서드를 래핑한 Since 메서드와 Until 메서드가 존재합니다.

 

 

 

 

2.  시간차이를 구하고싶은 메서드 앞뒤에 모두 time.now를 찍고 time.since를 호출해주면?

표준출력으로 실행시간의 로그를 찍어보라는 요구사항에 원하는 메서드 앞뒤에 모두 해당로직을 추가 하였지만

나중에 실행시간의 평균을 보고싶다고 해서 db에 넣어달라고 하는 요구사항이 생겨버렸습니다.

 

이런 경우 횡단 관심사를 분리해줘야 합니다.

 

횡단관심사를 분리하기 위해 java진영에는 AOP가, python 진영에는 decorator 어노테이션이 존재합니다.

 

고랭은 표준 라이브러리에서 어노테이션을 지원하지 않으므로 함수포인터를 사용하여 구축할 수 있습니다.

(함수포인터나 상속을 지원하는 언어에서는 타이머를 쉽게 구축할 수 있습니다.)

 

3. decorator!!

package main

import (
	"fmt"
	"time"
)

func main() {
   executeWithTimer(doSomething)
   executeWithTimer(doSomething2)
}

func doSomething() {
   for i := 0; i < 10; i++ {
      fmt.Println("test")
   }
}

func doSomething2() {
   for i := 0; i < 20; i++ {
      fmt.Println("test")
   }
}

// 요구사항이 변경되면 이 부분만 수정하도록 합니다.
func executeWithTimer(f func()) {
   startTime := time.Now()
   f()
   since := time.Since(startTime)
   fmt.Println(since)
}

 

기존에 "test" 를 출력하던 코드를 doSomething메서드로 빼준후

함수를 호출할때 executeWithTimer 메서드에 콜백 메서드로 넘겨 실행합니다.

이제 요구사항이 변경돼도 executeWithTimer 메서드만 수정하여 대응할 수 있습니다.

반응형

댓글