본문 바로가기
C.W.K.
Stream
Lesson 01 of 05 · published

부르는 쪽은 그 일을 배우면 안 돼

~12 min · boundaries, coupling, invariants, separation-of-concerns

Level 0불 꺼진 작업장
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

금지로 적힌 경계

아키텍처 경계는 보통 양쪽이 뭘 갖는지로 설명해. 이건 반대로 쓰여 있어. 한쪽에 대한 금지야. 두뇌는 영상을 절대 배우면 안 된다. 장면도 안 돼. 비트도 안 돼. 음성 구성도, 자막 타이밍도 안 돼. 조각이 아무리 작든, 거기 두는 게 아무리 편하든, 영원히 안 돼.

경계를 배분이 아니라 금지로 적는 건 의도적인 수야. 왜 그런지 알아둘 값어치가 있어. "영상은 작업장 소관"은 맞는 말인데 쓸모가 없어. 누가 반대편에 작은 헬퍼 하나 붙이자고 할 때 아무 답도 못 주거든. 작은 헬퍼는 영상 소유권을 가져오는 느낌이 안 나니까. "부르는 쪽은 영상을 안 배운다"는 그 제안에 바로 답해. 조각이 작다는 건 변명이 안 돼.

부르는 쪽한테 허락된 것

허용된 표면은 일부러 거의 아무것도 아니게 해뒀어. 버튼 하나, 한 줄짜리 입력칸 하나, 포인터를 메시지에 싸서 보내는 엔드포인트 하나. 다 합쳐 백 줄 아래. 파이프라인 이름 하나랑 물건 식별자 하나를 알아. 파이프라인이 뭘 하는지, 어떤 단계가 있는지, 판이 뭔지, 렌더링에 그림이 관여하긴 하는지조차 몰라.

이게 뭘 사주는지 봐. 부르는 쪽은 작업장을 한 번도 안 열어본 사람이 관리할 수 있어. 작업장은 내부를 통째로 갈아엎어도 돼. 단계 이름을 다 바꾸든, 렌더 포맷을 바꾸든, 음성 공급자를 갈아치우든, 부르는 쪽은 눈치도 못 채. 부르는 쪽이 가진 작업장 모형이 문자열 하나랑 식별자 하나거든. 이건 설계의 부작용이 아니라 설계 그 자체야.

무너지는 경로는 항상 똑같아

이런 경계는 극적인 결정 하나로 무너지는 일이 드물어. 단계마다 다 합리적인 연쇄로 무너져. 부르는 쪽에 미리보기 썸네일이 있으면 좋겠다 싶어서 이미지 로직이 조금 들어와. 다음은 길이 추정치고, 그러려면 구간에 대해 뭘 좀 알아야 해. 다음은 진행 표시줄이고, 그러려면 단계 목록을 알아야 하고. 하나씩 보면 다 방어가 돼. 도착지는 슬그머니 영상을 배워버린 호출자야. 그 시점엔 같은 지식의 구현이 둘이 되고, 둘은 반드시 어긋나.

적힌 금지는 1 단계를 눈에 보이게 하려고 있어. 아무나 막을 수 있었던 게 1 단계뿐이거든. 3 단계쯤 가면 되돌리는 값이 너무 커져서, 문서가 여전히 뭐라 주장하든 경계는 실질적으로 사라진 상태야.

Code

부르는 쪽에 허락된 표면 전부·python
@router.post("/api/beacon/flag")
async def flag_for_production(payload: FlagRequest) -> dict:
    """Emit a pointer. That is the whole job.

    Note what is absent: no duration estimate, no thumbnail, no
    progress field, no render status. Every one of those would
    require this file to know something about video.
    """
    send_request(
        scope="beacon",
        receiver="workshop-session",
        context={
            "pipeline": payload.pipeline,   # a name, not behavior
            "pointer": payload.pointer,     # {kind, id} - opaque here
            "why": payload.why,             # one optional line
        },
    )
    return {"ok": True}

# The caller cannot answer "is it done?" and must not grow the
# ability to. That question belongs to the thread, not to this route.
1 단계가 눈에 보이도록 적어둔 침식 순서·text
step 1  "just a preview thumbnail here"      -> needs image handling
step 2  "just a rough duration estimate"      -> needs segment model
step 3  "just a progress bar"                 -> needs the stage list
step 4  "we already have most of it, so..."   -> the boundary is gone

# Every step is individually reasonable.
# Only step 1 is cheap to refuse.
# This is why the rule names the DIRECTION, not the size.

External links

Exercise

네 코드베이스에서 배분으로 적혀 있는 경계를 하나 찾아봐. "결제 모듈이 청구 로직을 소유한다" 같은 거. 그걸 제일 침범할 것 같은 쪽을 겨냥한 금지로 다시 써보고, 위반을 찾아 나서. 다시 쓰기만 해도 보통 두세 개가 바로 튀어나와. 배분은 소유한 쪽이 존재하기만 하면 충족된 걸로 읽히거든.
Hint
침범하는 쪽은 거의 항상 사용자 인터페이스에 가까운 쪽이야. 작은 편의가 요청되는 자리가 거기니까. UI 계층이 지금 도메인에 대해 뭘 알고 있는지 물어봐. 도메인을 통째로 갈아치우면 다시 알려줘야 하는 것들 말이야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.