본문 바로가기
잡(job)기술/파이썬 공부

나의 파이썬 코드를 한 단계 끌어올릴 5가지 설계 원칙

by 무니이구나 2026. 1. 14.

 

파이썬으로 새 프로젝트를 시작하면 구조는 단순하다. 하지만 기능이 늘고 코드가 쌓일수록 구조는 빠르게 복잡해진다.

“이 코드는 어디에 둬야 하지?”
“이 함수 하나 고쳤는데 왜 다른 곳이 깨질까?”

 

이런 문제의 원인은 대부분 설계 기준 없이 코드가 쌓였기 때문이다. 이 글에서는 파이썬 프로젝트를 더 읽기 쉽고, 고치기 쉽고, 테스트하기 쉽게 만드는 다섯 가지 설계 원칙을 정리한다.


원칙 1: 기술이 아니라 ‘업무’ 기준으로 코드를 묶는다

많은 프로젝트가 이렇게 시작한다.

utils/
services/
helpers/
models/

 

처음에는 편하다. 하지만 프로젝트가 커지면 “이 기능이 어디에 있는지” 찾는 데 시간이 더 든다.

해결책: 도메인(업무) 기준 구조

쇼핑몰이라면 구조는 이렇게 나뉜다.

users/
products/
orders/
payments/

 

이 구조의 핵심은 단순하다.

“같은 일을 하는 코드는 같은 폴더에 둔다.”

 

예를 들어 users/ 안에는 다음이 함께 있다.

  • 사용자 모델
  • 사용자 관련 규칙
  • 사용자 저장/조회 코드

덕분에 기능 수정 시 한 폴더만 보면 된다.


원칙 2: 비즈니스 규칙은 인프라를 몰라야 한다

비즈니스 규칙은 “무엇이 올바른가”를 판단하는 코드다.

잘 설계된 함수의 책임

def create_user(data: dict) -> User:
    # 유효성 검사
    # 기본값 설정
    # 사용자 객체 생성
    return user

 

이 함수는 사용자를 어떻게 정의할지만 안다. 데이터베이스, 이메일, 메시지 큐는 모른다.

잘못된 예

def create_user(data: dict) -> User:
    db.session.add(user)
    db.session.commit()
    send_email(user.email)

 

이 함수는 너무 많은 것을 안다.

  • DB 기술
  • 트랜잭션 방식
  • 이메일 시스템

올바른 조립 방식 (유스케이스)

user = user_service.create_user(data)
user_repo.save(user)
email_service.send_welcome(user)

 

이렇게 하면 기술이 바뀌어도 비즈니스 규칙은 그대로 유지된다.


원칙 3: 코드의 역할을 명확히 구분한다

services.py 하나에 모든 로직을 넣으면 책임이 섞이고 테스트가 어려워진다.

핵심 역할 3가지

1️⃣ 도메인 서비스

 

역할

  • 순수한 비즈니스 규칙
  • 계산, 검증, 판단만 수행

특징

  • DB, 네트워크, 파일 시스템을 모름
  • 테스트가 가장 쉬움
def can_upgrade_plan(user, plan):
    return user.level >= plan.required_level

2️⃣ 레포지토리 (Repository)

역할

  • 데이터를 저장하고 불러옴
  • DB 기술을 감춤
class UserRepository:
    def save(self, user): ...
    def get_by_email(self, email): ...

 

도메인 서비스는 “어디에 저장되는지”를 신경 쓰지 않는다.


3️⃣ 애플리케이션 서비스

역할

  • 하나의 유스케이스를 완성
  • 여러 컴포넌트를 조합
def register_user(data):
    user = create_user(data)
    user_repo.save(user)
    email_service.send_welcome(user)

역할과 의존성 방향

의존성은 항상 위에서 아래로만 흐른다.


원칙 4: 순환 참조는 설계가 깨졌다는 신호다

다음 구조를 상상해보자.

users → payments
payments → users

 

이 상태에서는:

  • 하나를 고치면 다른 쪽이 깨짐
  • import 에러 발생
  • 테스트가 어려워짐

해결 전략

  1. 공통 규칙을 상위 레이어로 이동
  2. 의존성 방향을 단방향으로 재설계
payments → users
users ✕ payments

 

순환 참조는 “임시 해결”의 대상이 아니라 “구조를 다시 보라”는 경고다.


원칙 5: 표준 구조는 목표가 아니라 시작점이다

많은 프로젝트가 이렇게 시작한다.

src/
  project/
tests/

 

이 구조는 나쁘지 않다. 하지만 구조만 있고 원칙이 없으면 의미가 없다.

좋은 구조는 다음을 만족한다.

  • 업무 기준으로 나뉘어 있고
  • 비즈니스와 인프라가 분리되어 있으며
  • 의존성이 단방향이고
  • 테스트가 쉽다

예제: 회원가입 유스케이스 흐름

 

이 구조의 장점은 명확하다.

  • 도메인 서비스는 단위 테스트 가능
  • DB 없이도 비즈니스 규칙 검증 가능
  • 인프라 교체 비용이 낮음

마무리: 설계는 복잡함을 줄이기 위한 도구다

다섯 가지 원칙은 서로 연결되어 있다.

  1. 업무 기준으로 구조를 잡고
  2. 비즈니스와 인프라를 분리하고
  3. 역할을 명확히 나누며
  4. 의존성을 단순하게 유지하고
  5. 구조를 출발점으로 삼는다

이 원칙을 적용하면 프로젝트는:

  • 테스트하기 쉬워지고
  • 리팩터링이 덜 무서워지며
  • 시간이 지나도 유지보수가 가능해진다

완벽하게 시작할 필요는 없다. 하나의 원칙만 의식하는 것이 설계의 출발점이다.