모듈러 모놀리딕과 파이썬 예제 #1
모률러 모놀리딕(Modular Monolithic) 아키텍처는 시스템을 하나의 단일 프로세스(Monolithic)로 배포하되, 내부 코드는 독립적인 모듈(Module)단위로 엄격하게 분리하여 결합도를 낮추는 아키텍처입니다. 각 모듈은 내부 구현을 숨기고(캡슐화), 명확한 인터페이스를 통해서만 소통해야 합니다.
기본예제 Project를 main.py | cli.py | feature_a.py | feature_b.py 로 구성하였고, 파이썬으로 언어입니다.
- main.py 애플리케이션 진입
- cli.py 사용자 인터페이스 입/출력 담당 모듈
- feature_a.py 비지니스 로직 A 모듈
- feature_b.py 비지니스 로직 B 모듈
1. 비지니스 로직 A 모듈 (feature_a.py)
외부에는 데이터를 처리하는 핵심 인터페이스(run)만 노출하고, 내부 동작 알고리즘(_secret_process)은 숨김힙니다.
외부에는 데이터를 처리하는 핵심 인터페이스(run)만 노출하고, 내부 동작 알고리즘(_secret_process)은 숨김힙니다.
# feature_a.pydef _secret_process(data: str) -> str:"""모듈 내부에서만 사용하는 캡슐화된 메서드 (Private)"""return f"[A 모듈 가공] -> {data}"def run(input_value: str) -> str:"""외부에서 호출하는 명확한 Public API 인터페이스"""print("⚙️ A 기능 모듈 작동 중...")result = _secret_process(input_value)return f"A 기능 완료 결과: {result}"
2. 비지니스 로직 B 모듈 (feature_b.py)
A 모듈과 완전히 독립되어 있으며, 자신만의 비즈니스 로직을 수행합니다.
# feature_b.pydef run(input_value: str) -> str:"""외부에서 호출하는 명확한 Public API 인터페이스"""print("⚙️ B 기능 모듈 작동 중...")# 간단한 비즈니스 로직 예시 (역순 정렬)reversed_data = input_value[::-1]return f"B 기능 완료 결과: {reversed_data}"
3. 입출력 담당 모듈 (cli.py)
비지니스 로직(A, B)이 어떻게 돌아가는지 전혀 알 필요가 없습니다. 오직 사용자에게 입력을 받고 결과를 출력하는 UI역할에만 충실합니다.
# cli.pydef get_user_choice() -> tuple[str, str]:"""사용자로부터 메뉴 선택과 입력값을 받는 인터페이스"""print("\n==============================")print("1: A 기능 실행")print("2: B 기능 실행")print("q: 프로그램 종료")print("==============================")choice = input("원하는 기능을 선택하세요: ").strip()if choice == 'q':return choice, ""user_input = input("기능에 전달할 텍스트를 입력하세요: ")return choice, user_inputdef display_result(result: str):"""결과 화면을 출력하는 인터페이스"""print("\n📢 [CLI 출력]")print(f"결과: {result}")
4. 진입점 및 모듈 조립 (main.py)
애플리케이션을 초기화하고, 각 모듈의 인터페이스를 연결하는 역할을 합니다. 중요한 점은 A모듈과 B모듈이 서로 참조하지 않고, CLI모듈도 A, B을 알지 못하며, 오직 main.py가 이들을 중재한다는 것입니다.
# main.pyimport cliimport feature_aimport feature_bdef bootstrap():"""프로그램 초기 실행 및 준비 단계"""print("🚀 시스템 초기화 중... 모듈 로드 완료.")print("모듈러 모놀리딕 애플리케이션을 시작합니다.")def main():bootstrap()while True:# 1. CLI 모듈을 통해 사용자 입력 수집choice, user_data = cli.get_user_choice()if choice == 'q':print("👋 프로그램을 종료합니다.")break# 2. 제어 흐름 분기 및 모듈 간 중재result = ""if choice == '1':# CLI에서 받은 데이터를 A 모듈 인터페이스로 전달result = feature_a.run(user_data)elif choice == '2':# CLI에서 받은 데이터를 B 모듈 인터페이스로 전달result = feature_b.run(user_data)else:result = "❌ 잘못된 선택입니다. 다시 시도하세요."# 3. 처리된 결과를 다시 CLI 모듈을 통해 출력cli.display_result(result)if __name__ == "__main__":main()
모듈러 아키텍처 관점에서의 핵심 포인트
- 낮은 결함도(Low Coupling) : feature_a.py와 feature_b.py는 서로의 존재를 모릅니다. 나중에 B기능을 삭제하거나, C기능으로 대체해도 A기능에 영향이 없습니다.
- 높은 응집도(High Cohesion) : cli.py는 입출력만 담당하고, feature_a는 본인의 데이터 처리에만 집중합니다. UI가 웹(Web)이나 GUI로 바뀌더라도 cli.py만 수정하거나 교체하면 됩니다.
- 단일 진입점(Single Entry Point) : main.py가 전체 흐름을 제어하는 컨트롤 타워 역할을 수행하여 모듈 간의 무분별한 직접 참조(Spaghetti Code)를 방지합니다.
모듈러 모놀리딕 배포관점 및 개발/논리 관점
- 배포관점 : 전체 시스템이 하나의 거대한 '애플리케이션'으로 묶여 있으며, 단일 프로세스와 메모리 공간을 공유합니다. 배포관점은 모놀리딕 입니다.
- 개발/논리 - 아키텍처 관점 : 시스템 내부가 모듈별로 엄격하게 분리되어 있습니다. 각 모듈은 자신만의 내부 로직과 데이터 액세스 계층을 가지며, 외부에는 명확한 'Public API 인터페이스'만 노출하여 소통합니다.

댓글 없음:
댓글 쓰기