레지스트리(Registry) 패턴 쉽게 이해하기
개발하다 보면 이런 상황이 자주 생긴다.
- 기능이 몇 개 없을 땐 if-else로 처리 가능
- 근데 도메인/툴이 계속 늘어나면?
- 파일 수정이 계속 발생하고 코드가 점점 더러워짐
이 문제를 깔끔하게 해결하는 패턴이 바로 Registry(레지스트리) 패턴이다.
1. 레지스트리 패턴이란?
레지스트리 패턴은 쉽게 말해서
이름(key) → 객체(또는 클래스) 를 매핑해서 저장해두는 구조
즉, 문자열 이름만 알면 해당 기능을 찾아서 실행할 수 있도록 하는 패턴이다.
2. 비유로 이해하기: 전화번호부
레지스트리를 전화번호부로 생각하면 쉽다.
📒 레지스트리 = 전화번호부
예를 들어 전화번호부에는 이런 정보가 들어있다.
- "김김김" → 010-1234-5678
- "박땡땡" → 010-9876-5432
이름만 알면 전화번호를 바로 찾을 수 있는 구조.
코드에서는 이렇게 대응된다
- "member_info" → MemberInfoTool
- "book_order" → BookOrderTool
즉, 툴 이름만 알면 해당 툴 클래스를 찾아서 실행 가능한 것
3. 레지스트리 없을 때: if-else 지옥
레지스트리를 사용하지 않으면 보통 이런 코드가 된다.
# tools.py - 새 도메인 추가할 때마다 여기 수정해야 함
def get_tool(name):
if name == "member_info":
return MemberInfoTool()
elif name == "book_order":
return BookOrderTool()
elif name == "lecture_order": # 추가
return LectureOrderTool()
elif name == "reimbursement": # 추가
return ReimbursementTool()
# ... 계속 늘어남
문제점
- 새로운 Tool 추가할 때마다 if-else 계속 추가
- 코드가 계속 길어지고 유지보수 어려움
- 도메인이 10개, 20개, 50개 되면 관리 불가능
결국 이 구조는 확장성이 매우 떨어진다.
4. 레지스트리 있을 때: 전화번호부에 등록하고 찾기
레지스트리 패턴을 적용하면 구조가 완전히 달라진다.
registry.py (전화번호부 역할)
# registry.py
class SnowflakeToolRegistry:
_registry = {} # 빈 전화번호부
@classmethod
def register(cls, tool_class):
"""전화번호부에 등록"""
name = tool_class._tool_name.tool_name
cls._registry[name] = tool_class
return tool_class
@classmethod
def get(cls, name):
"""전화번호부에서 찾기"""
tool_class = cls._registry.get(name)
return tool_class() if tool_class else None
이제 registry는 내부적으로 이렇게 저장하게 된다.
5. 툴 파일에서는 등록만 하면 끝
# book_order.py
@SnowflakeToolRegistry.register
class BookOrderTool:
_tool_name = ToolName.BOOK_ORDER # "book_order"
툴을 추가할 때 @register만 붙이면 자동으로 registry에 들어간다.
즉, 새로운 툴을 추가해도 기존 파일을 수정할 필요가 없다.
6. tools.py는 더 이상 수정 필요 X
# tools.py
def get_tool(name):
return SnowflakeToolRegistry.get(name)
이제 get_tool 함수는 항상 registry만 바라보면 된다.
7. @데코레이터가 실제로 하는 일
많이 헷갈리는 부분이 데코레이터(@register)인데,
실제로는 아래 코드와 완전히 동일하다.
# 데코레이터 코드
@SnowflakeToolRegistry.register
class BookOrderTool:
...
# 실제 동작 코드
class BookOrderTool:
...
BookOrderTool = SnowflakeToolRegistry.register(BookOrderTool)
클래스가 정의되는 순간 자동으로 registry에 등록
8. 실제 동작 흐름 (앱 실행 순서)
레지스트리 패턴은 결국 import될 때 동작한다.
1) 앱 시작 시 import
2) import되면서 @register 실행
3) 나중에 LLM이 "book_order" 호출
4) tool 실행
9. 레지스트리 패턴의 장점
✅ 확장성
- Tool이 10개든 100개든 registry 구조는 동일
✅ 유지보수성
- 기존 코드 수정 없이 Tool 파일만 추가하면 됨
✅ 플러그인 구조에 적합
- LangGraph, LangChain Agent 구조에서 매우 유용
10. 핵심 요약
| 레지스트리 | 이름 → 클래스 매핑하는 전화번호부 |
| @register | 전화번호부에 자동 등록하는 스티커 |
| 장점 | 새로운 도메인 추가해도 기존 코드 수정 불필요 |
11. 한 줄 정리
"이름표 붙여서 창고에 넣어두고, 나중에 이름으로 꺼내 쓰는 패턴"
결론
레지스트리 패턴 == "Tool 이름으로 실행해야 하는 구조"에서 거의 필수적인 패턴
if-else로 Tool을 관리하는 구조는 확장성에 한계도 있고 코드가 지저분해지지만,
레지스트리 패턴을 적용하면 코드가 훨씬 깔끔해지고 유지보수도 쉬워진다.
'Python' 카테고리의 다른 글
| ERROR: Failed to build 'flash_attn' when getting requirements to build wheel (0) | 2026.01.15 |
|---|---|
| fara-7b 모델 테스트 (0) | 2025.12.01 |
| [Anaconda Prompt] 파이썬 아나콘다 & 케라스 설치 / tensorflow 설치 시 에러 (0) | 2023.03.20 |