약간의 복사가 약간의 의존성보다 낫다

백엔드&인프라 추종자·2025년 11월 20일

개인생각

조급한 추상화가 만악의 근원이라니.. 공감이 된다..


정말 좋은 포인트입니다! 개발자라면 당연히 "이거 나중에도 또 쓸 것 같은데? 재사용할 수 있게 만들까?" 라는 고민을 해야 합니다.

Go 언어 생태계에서는 이 "재사용성"을 다루는 3가지 단계가 있습니다. 현재 상황에 맞춰 선택하시면 됩니다.


1. internal vs pkg (프로젝트 내 위치 결정)

Go에는 internal 이라는 특수한 디렉토리 규칙이 있습니다.

  • internal/: 이 폴더 안에 있는 코드는 오직 이 프로젝트(모듈) 안에서만 import 할 수 있습니다. 외부 프로젝트에서 가져다 쓰려고 하면 컴파일 에러가 납니다.
  • pkg/ (또는 루트): 여기에 두면 다른 프로젝트에서도 import "github.com/내계정/내프로젝트/pkg/storage" 형식으로 가져다 쓸 수 있습니다.

추천 전략:

지금 만드시는 MinIO, RabbitMQ 코드가 **"이 프로젝트만을 위한 설정(Config)"**이 많이 섞여 있다면 internal에 두는 게 맞습니다. 하지만, 정말 범용적인 라이브러리(Wrapper) 처럼 짰다면 폴더 이름을 pkg로 바꾸는 것만으로도 공유 가능해집니다.

myproject/
├── internal/       <-- 우리 프로젝트만의 비즈니스 로직
│   └── fileconv/
└── pkg/            <-- 남들도 갖다 써도 되는 범용 유틸리티
    ├── storage/
    └── queue/

2. Go 커뮤니티의 명언: "복붙도 기술이다"

Go 창시자 중 한 명인 롭 파이크(Rob Pike)는 이런 말을 했습니다.

"약간의 복사(Copying)가 약간의 의존성(Dependency)보다 낫다."
("A little copying is better than a little dependency.")

MinIO나 RabbitMQ 연결 코드는 보통 파일 1~2개 분량(50~100줄) 정도입니다. 이걸 공유하기 위해 별도 라이브러리를 만들고 관리하는 비용보다, 그냥 새 프로젝트에 파일을 복사해서 붙여넣는 것이 훨씬 깔끔할 때가 많습니다.

이유:

  • 프로젝트 A는 MinIO 타임아웃을 30초로 하고 싶고, 프로젝트 B는 5초로 하고 싶을 수 있습니다.
  • 공통 라이브러리로 묶어두면, 이거 하나 고칠 때 모든 프로젝트가 영향을 받습니다(결합도 증가).

3. 진짜 "공용 라이브러리" (Go Module) 만들기

만약 회사에서 마이크로서비스를 10개, 20개씩 만들고 있어서 MinIO 연결 코드를 매번 복사하는 게 관리가 안 된다면, 그때는 별도의 Git 저장소를 파는 것이 정석입니다.

예시: company-kit 레포지토리 생성

  1. github.com/mycompany/go-kit 라는 새 저장소를 만듭니다.
  2. 여기에 storage, queue, logger 같은 공통 패키지를 몰아넣습니다.
  3. 각 프로젝트(file-conv, image-resize 등)에서 go get github.com/mycompany/go-kit 명령어로 당겨와서 씁니다.

결론 및 추천

지금 혼자 개발하시거나 프로젝트가 2~3개 정도라면:

  1. 일단 internal/infra/storage (또는 pkg/storage)에 작성하세요.
  2. 다른 프로젝트를 할 때 똑같은 게 필요하면? 일단 파일을 복사해서 가져가세요. (Go스러운 방식)
  3. 복사한 코드가 3~4번 이상 반복되고, 로직이 수정될 때마다 4군데 다 고치는 게 너무 힘들다면? 그때 별도 common 레포지토리로 분리하세요.

**"조급한 추상화(Premature Abstraction)는 만악의 근원"**이라는 말이 있습니다. 지금은 현재 프로젝트를 완성하는 데 집중하고, internal에 두시는 것을 추천합니다!

profile
AI 답변 글을 주로 올립니다.

0개의 댓글