Differences between revisions 1 and 3 (spanning 2 versions)
Revision 1 as of 2025-12-29 20:28:27
Size: 29548
Editor: 정수
Comment:
Revision 3 as of 2025-12-30 09:07:55
Size: 13552
Editor: 정수
Comment:
Deletions are marked like this. Additions are marked like this.
Line 9: Line 9:
== The Story: The Search for the Right Name ==

주니어 개발자 수진은 주문 처리 시스템을 작성하고 있었다. 그는 변수 이름을 짓다가 막혔다.
== The Story 1: The Search for the Right Name (Programming) ==

주니어 개발자 주문 처리 시스템을 작성하고 있었다. 그는 변수 이름을 짓다가 막혔다.
Line 22: Line 22:
"이건 너무 못생겼어..." 수진은 생각했다. 30분 동안 고민한 끝에:

{{{
def calculate_order_total_amount_including_all_items(order_data):
    list_of_order_items = order_data['items']
    total_amount_to_be_paid = 0
    for individual_item in list_of_order_items:
        total_amount_to_be_paid += individual_item['price'] * individual_item['qty']
    return total_amount_to_be_paid
}}}

"더 명확해졌어!" 하지만 코드 리뷰에서:

시니어 개발자 민호가 말했다. "수진, 이건 오히려 더 읽기 어려워. 이름이 너무 길고, 중복이 많아."

"하지만 명확하게 하려고..."

"명확함은 길이가 아니라 '''문맥'''에서 나와. 봐봐:"

{{{
def total(order):
    return sum(item.price * item.quantity for item in order.items)
}}}

"짧네요! 하지만 무엇의 total인지 어떻게 알아요?"

민호가 더 큰 코드를 보여주었다:
"이건 너무 못생겼어..." 민수는 생각했다. 30분 동안 고민한 끝에 이름을 아주 길게 고쳤다. `calculate_order_total_amount_including_all_items(order_data)`. 하지만 코드 리뷰에서 하나가 말했다.

"민수님, 명확함은 길이가 아니라 '''문맥'''에서 나와요. 봐요."
Line 64: Line 40:
"봐, `order.total()`이라고 쓰면 '''Order의 total'''이라는 게 명확해. 문맥이 이름을 완성하는 거야. 그리고 `Item.subtotal()`은 '''Item의 소계'''라는 게 바로 보이지?"

수진의 눈이 커졌다. "아... 이름은 혼자 존재하는 게 아니라 '''관계 속에서''' 의미를 갖는 거군요!"

"정확해. 이름 짓기는 단순히 라벨을 붙이는 게 아니야. 그것은 '''설계 활동'''이야. 좋은 이름은 좋은 설계를 반영해."
"봐요, `order.total()`이라고 쓰면 '''Order의 total'''이라는 게 명확하죠? 문맥이 이름을 완성하는 거예요. 그리고 `Item.subtotal()`은 '''Item의 소계'''라는 게 바로 보이지요? 이름은 혼자 존재하는 게 아니라 '''관계 속에서''' 의미를 갖는 거예요. 이름 짓기는 단순히 라벨을 붙이는 게 아니라, 좋은 설계를 반영하는 '''설계 활동''' 그 자체입니다."


== The Story 2: The Baby's Name (Ordinary Life) ==

민수와 하나는 곧 태어날 아기의 이름을 고민하고 있다.

'''민수의 작명 (The Functional Name):'''
민수는 실용적인 이름을 원한다. "우리 첫째니까 그냥 '민수 주니어 1호'라고 부르면 어때? 누가 봐도 내 아들인 걸 알 수 있잖아." 민수에게 이름은 단순히 대상을 식별하기 위한 라벨일 뿐이었다. 하지만 '1호'라는 이름은 아이의 개성이나 가족 안에서의 정체성을 전혀 담아내지 못했다.

'''하나의 작명 (The Design Name):'''
하나는 이름이 아이의 삶을 설계하는 첫 번째 단추라고 생각한다. "아이의 이름은 성(Last name)과 조화로워야 하고, 나중에 자라서 사회에서 불릴 때의 느낌도 고려해야 해." 하나는 아이가 평생 불릴 문맥을 상상하며 이름을 골랐다. "밝게 빛나라는 뜻의 '윤(潤)'을 넣자. 우리 가족의 따뜻한 분위기와도 잘 어울려." 이름이 정해지자 아이의 방을 어떻게 꾸밀지, 어떤 옷을 입힐지 같은 '설계'가 자연스럽게 뒤따랐다. 이름은 단순한 라벨이 아니라, 존재의 본질을 규정하는 설계의 시작임을 하나는 알고 있었다.
Line 73: Line 56:
당신은 코드를 작성하면서 변수, 함수, 클래스, 모듈에 이름을 붙여야 한다. 이름은 코드의 모든 곳에 있고, 코드를 읽는 사람(미래의 자신을 포함해서)이 가장 먼저 보는 것이다. 당신은 코드를 작성하면서 변수, 함수, 클래스, 모듈에 이름을 붙여야 한다. 이름은 코드의 모든 곳에 있고, 코드를 읽는 사람이 가장 먼저 보는 것이다.
Line 78: Line 61:
 * 변수 이름을 `data`, `temp`, `x` 같은 일반적 이름으로 짓는다
 * 함수 이름을 너무 길게 만든다 (`calculateOrderTotalAmountIncludingTax`)
 * 같은 개념을 여러 이름으로 부른다 (`user` / `customer` / `account`)
 * 이름을 짓는 데 과도한 시간을 쓰거나, 거의 생각 없이 짓는다
 * 변수 이름을 `data`, `temp`, `x` 같은 일반적 이름으로 짓는다.
 * 함수 이름을 너무 길게 만든다 (`calculateOrderTotalAmountIncludingTax`).
 * 같은 개념을 여러 이름으로 부른다 (`user` / `customer` / `account`).
 * 이름을 짓는 데 과도한 시간을 쓰거나, 거의 생각 없이 짓는다.
Line 89: Line 72:
Line 91: Line 73:

'''너무 빠른 네이밍'''
{{{
def
f(x):
   y = x['a']
   z = 0
    for i in y:
        z += i['b'] * i['c']
    return z
}}}
 *
빠르지만 의미 없
* 1주일 후 자신도 이해 못 함
 * "코드가 스스로 말한다"는 원칙 위반

'''너무 긴 네이밍'''
{{{
def
calculate_total_amount_of_order_including_all_line_items_with_quantities():
   list_of_all_items_in_current_order = ...
}}}
 *
명확하려 했지만 장황
 *
읽기 어려
* 중복 정보 (order의 total이면 당연히 items 포함)
 * '''너무 빠른 네이밍:''' `f(x)`, `y = x['a']` 처럼 빠르지만 의미 없 이름을 붙인다. 1주일 후 자신도 이해하지한다.
 * '''너무 긴 네이밍:''' `calculate_total_amount_of_order_including_all_line_items()` 처럼 명확하려 했지만 장황하고 읽기 어려 이름을 만든다.
Line 115: Line 77:

Phil Karlton이 말했다: '''"There are only two hard things in Computer Science: cache invalidation and naming things."'''

왜 네이밍이
어려운가? 많은 프로그래머가 착각한다:

'''잘못된 믿음:'''
 *
"좋은 이름은 그 자체로 명확해야 한다"
 * "이름만 보고 모든 것을 알 수 있어야 한다"
 *
"길고 자세할수록 좋다"

'''진실:'''
 * '''
이름 자체로는 좋고 나쁨을 판단할 수 없다'''
 *
'''문맥에 embedding되었을 때 평가할 수 있다'''
 * '''
관계 속에서 의미가 만들어진다'''
Phil Karlton은 "컴퓨터 과학에서 어려운 것은 딱 두 가지뿐이다. 캐시 무효화와 이름 짓기"라고 했다. 왜 네이밍이 어려운가?
 * '''잘못된 믿음:''' "좋은 이름은 그 자체로 명확해야 한다", "길고 자세할수록 좋다."
 * '''진실:''' 이름 자체로는 좋고 나쁨을 판단할 수 없다. '''문맥에 embedding되었을 때''' 평가할 수 있다. 관계 속에서 의미가 만들어지기 때문이다.
Line 131: Line 82:

주니어는 이름을 '''고립되어''' 생각한다:

{{{
# 이 이름이 좋은가?
calculate_total()

# 판단 불가능! 문맥이 없다.
}}}

하지만 이름은 '''관계망''' 속에 존재한다:

{{{
# 같은 이름, 다른 평가
class Order:
    def calculate_total(self): # ❌ 너무 장황
        ...

# vs

class Order:
    def total(self): # ✅ 문맥상 명확
        ...

# 사용할 때:
order.total() # "Order의 total" - 명확!
}}}

이름의 품질은:
 * '''부모와의 관계''' (`Order.total` - Order가 문맥 제공)
 * '''형제와의 관계''' (`total`, `subtotal`, `tax` - 일관된 어휘)
 * '''자식과의 관계''' (함수 내부가 이름과 일치하는지)
주니어는 이름을 '''고립되어''' 생각한다. 하지만 이름은 관계망 속에 존재한다. `order.total()`이라고 쓰면 'Order'라는 부모가 문맥을 제공하기 때문에 짧은 이름으로도 충분히 명확해진다. 이름의 품질은 부모, 형제, 자식과의 관계 속에서 결정된다.
Line 165: Line 85:

더 깊은 문제: '''이름은 설계의 표면이다.'''

나쁜 이름은 종종 나쁜 설계를 반영한다:

{{{
# 이름 짓기 어렵다면...
def process_user_data_and_send_email_and_update_database(user):
    # 이 함수는 너무 많은 일을 한다!
    # 이름의 문제가 아니라 설계의 문제
    ...
}}}

좋은 이름을 찾기 어렵다는 것은:
 * 개념이 불명확하다는 신호
 * 책임이 잘못 분배되었다는 신호
 * 추상화가 잘못되었다는 신호

'''네이밍 문제 = 설계 문제'''
이름은 설계의 표면이다. 나쁜 이름은 종종 나쁜 설계를 반영한다. 이름 짓기가 어렵다는 것은 개념이 불명확하거나, 책임이 잘못 분배되었거나, 추상화가 잘못되었다는 신호다.
Line 186: Line 88:

이름은 단순한 라벨이 아니다. '''이름은 개념 그 자체다.'''

{{{
# 같은 것, 다른 개념화
items = [...] # 단순 리스트
shopping_cart = [...] # 쇼핑 맥락
pending_orders = [...] # 주문 맥락
}}}

이름을 바꾸면 생각이 바뀐다:
 * `data` → `user` : 추상적 데이터에서 구체적 사용자로
 * `process()` → `authenticate()` : 무엇을 하는지 명확해짐
 * `flag` → `is_valid` : boolean의 의미가 명확해짐

'''좋은 이름을 짓는다 = 잘 개념화한다'''
이름은 단순한 라벨이 아니라 '''개념 그 자체'''다. `items`를 `shopping_cart`라고 부르는 순간, 단순한 리스트가 쇼핑이라는 맥락을 가진 개념으로 변한다. 이름을 바꾸면 생각이 바뀐다.
Line 204: Line 91:

좋은 이름은 주석보다 가치있다:

{{{
# ❌ 나쁜 이름 + 좋은 주석
# 사용자의 나이가 18세 이상인지 확인
def check(u):
    return u['age'] >= 18

# ✅ 좋은 이름, 주석 불필요
def is_adult(user):
    return user.age >= LEGAL_AGE
}}}

Ward Cunningham이 말했다: '''"Clean code is when each function does pretty much what you expected."'''

예상을 만드는 것이 바로 '''이름'''이다.
좋은 이름은 주석보다 가치 있다. "Clean code is when each function does pretty much what you expected." (Ward Cunningham). 그 예상을 만드는 것이 바로 이름이다.
Line 228: Line 99:
Line 230: Line 100:

=== Small Context (함수 내부) ===

{{{
# ❌ 문맥 무시
def calculate_total(list_of_order_items):
    total_amount = 0
    for individual_order_item in list_of_order_items:
        total_amount += individual_order_item['price']
    return total_amount

# ✅ 문맥 활용
def calculate_total(items):
    total = 0
    for item in items:
        total += item.price
    return total

# ✅✅ 더 나은 문맥
def calculate_total(items):
    return sum(item.price for item in items)
}}}

짧은 스코프에서는 짧은 이름이 명확하다. 문맥이 이미 충분한 정보를 제공하기 때문이다.

=== Large Context (클래스, 모듈) ===

{{{
# 클래스 문맥
class Order:
    def total(self): # "Order의 total"
        ...
    def subtotal(self): # "Order의 subtotal"
        ...
    def tax(self): # "Order의 tax"
        ...

# 사용할 때 문맥이 의미를 만든다
order.total() # 무엇의 total인지 명확
order.subtotal() # Order의 subtotal
order.tax() # Order의 tax
}}}

클래스/모듈 이름이 '''문맥'''을 제공한다. 메서드 이름은 그 문맥에서 평가된다.
 * '''Small Context (함수 내부):''' 짧은 스코프에서는 `total`, `items` 처럼 짧은 이름이 명확하다.
 * '''Large Context (클래스, 모듈):''' `Order.total()` 처럼 클래스 이름이 문맥을 제공할 때 메서드 이름은 간결해질 수 있다.
Line 276: Line 104:
Line 278: Line 105:

=== Siblings (형제 관계) ===

같은 레벨의 이름들은 일관된 패턴을 따라야 한다:

{{{
# ❌ 형제들이 안 어울림
class User:
    def get_name(self): # get_
        ...
    def fetchAge(self): # fetch (카멜케이스)
        ...
    def email(self): # 그냥 명사
        ...

# ✅ 형제들이 잘 어울림
class User:
    def name(self):
        ...
    def age(self):
        ...
    def email(self):
        ...
}}}

일관성이 예측 가능성을 만든다.

=== Parent-Child (부모-자식 관계) ===

부모(클래스)와 자식(메서드)이 조화로워야 한다:

{{{
# ❌ 중복
class OrderCalculator:
    def calculate_order_total(self): # Order가 두 번
        ...

# ✅ 조화
class Order:
    def total(self): # Order + total = "주문의 합계"
        ...

class Calculator:
    def calculate(self): # Calculator + calculate = 자연스러움
        ...
}}}
 * '''Siblings (형제 관계):''' 같은 레벨의 이름들은 일관된 패턴을 따라야 한다 (`name()`, `age()`, `email()`).
 * '''Parent-Child (부모-자식 관계):''' 부모와 자식이 조화로워야 한다. `OrderCalculator.calculate_order_total()`은 중복이다. `Order.total()`이 더 자연스럽다.
Line 326: Line 109:
Line 328: Line 110:

=== Problem Space Names (도메인 언어) ===

{{{
# 비즈니스 도메인의 이름
class Order:
    def place(self): # 도메인 용어
        ...
    def ship(self):
        ...
    def cancel(self):
        ...

class Customer:
    def purchase(self):
        ...
}}}

도메인 전문가와 대화할 때 사용하는 단어들이 코드에 그대로 있어야 한다. '''Ubiquitous Language''' (Eric Evans, DDD).

=== Solution Space Names (기술 언어) ===

{{{
# 기술적 구현의 이름
class OrderRepository:
    def save(self):
        ...
    def find_by_id(self):
        ...

class EventBus:
    def publish(self):
        ...
    def subscribe(self):
        ...
}}}

기술적 패턴과 메커니즘은 기술 용어로.
 * '''Problem Space Names (도메인 언어):''' `Order.place()`, `Customer.purchase()` 처럼 비즈니스 전문가와 공유하는 보편 언어(Ubiquitous Language)를 사용하라.
 * '''Solution Space Names (기술 언어):''' `OrderRepository`, `EventBus` 처럼 기술적 패턴은 기술 용어로 표현하라.
Line 368: Line 114:
Line 370: Line 115:

=== Discovery Through Naming ===

이름을 찾는 과정은 '''개념을 발견하는 과정'''이다:

{{{
# 진화 과정
data # 너무 일반적 - 개념 불명확
user_data # 조금 나아짐 - 사용자와 관련
profile # 더 구체적 - 프로필이라는 개념 발견
user_profile # 명확 - 사용자의 프로필
}}}

이름이 명확해지는 과정 = 개념이 명확해지는 과정.

=== Boolean Names ===

Boolean은 질문으로 이름 지어라:

{{{
# ❌ 애매함
flag = True
status = False

# ✅ 명확한 질문
is_valid = True
has_permission = False
can_edit = True
should_retry = False
}}}

`is_`, `has_`, `can_`, `should_` 접두사가 의도를 명확히 한다.
이름을 찾는 과정은 개념을 발견하는 과정이다. `data` -> `user_data` -> `user_profile`로 이름이 명확해지는 과정은 설계가 정교해지는 과정과 일치한다.
Line 404: Line 118:
Line 406: Line 119:

{{{
# ❌ 주석 의존
# 사용자가 성인인지 확인
def check(u):
    return u['a'] >= 18

# ✅ 자체 문서화
def is_adult(user):
    return user.age >= LEGAL_ADULT_AGE
}}}

Robert C. Martin이 말했다: '''"The proper use of comments is to compensate for our failure to express ourselves in code."'''

이름으로 표현하지 못해서 주석을 쓴다. 좋은 이름은 주석을 불필요하게 만든다.
"The proper use of comments is to compensate for our failure to express ourselves in code." (Robert C. Martin). 이름으로 표현하지 못해서 주석을 쓰는 것이다.
Line 423: Line 122:

'''[[MetaphorThinking]]''' - 좋은 은유는 좋은 이름을 만든다.

{{{
# 은유 활용
class Stack: # "쌓다" - 물리적 은유
    def push(item): # 밀어넣다
    def pop(): # 꺼내다

class Queue: # "줄" - 물리적 은유
    def enqueue(item): # 줄에 서다
    def dequeue(): # 줄에서 나가다

class Stream: # "흐름" - 물리적 은유
    def read():
    def write():
    def flush(): # 흘려보내다
}}}

은유가 직관적 이해를 만든다.
'''[[MetaphorThinking]]''' - 좋은 은유는 좋은 이름을 만든다. `Stack.push()`, `Queue.enqueue()`, `Stream.flush()` 처럼 은유가 직관적 이해를 돕는다.
Line 445: Line 125:

'''[[LanguageBuilding]]''' - 이름들은 의미 네트워크를 형성한다.

{{{
# 의미적으로 연결된 이름들
class Order:
    def total(self): # 전체
        return self.subtotal() + self.tax()

    def subtotal(self): # 부분 합계
        return sum(item.subtotal() for item in self.items)

    def tax(self): # 세금
        return self.subtotal() * self.tax_rate

class Item:
    def subtotal(self): # 항목의 소계
        return self.price * self.quantity
}}}

`total`, `subtotal`, `tax` - 이 단어들은 서로 관계를 형성한다. 하나를 보면 다른 것을 예상할 수 있다.
'''[[LanguageBuilding]]''' - 이름들은 의미 네트워크를 형성한다. `total`, `subtotal`, `tax` - 이 단어들은 서로 관계를 형성하며 하나를 보면 다른 것을 예상할 수 있게 한다.
Line 471: Line 131:

'''진화 과정:'''

{{{
# V1: 일반적
def process(data):
    result = []
    for item in data:
        result.append(item * 2)
    return result

# V2: 조금 나아짐
def process_numbers(numbers):
    doubled = []
    for num in numbers:
        doubled.append(num * 2)
    return doubled

# V3: 명확한 의도
def double_prices(prices):
    return [price * 2 for price in prices]

# V4: 도메인 언어
def apply_inflation(prices, rate=2.0):
    return [price * rate for price in prices]
}}}

각 단계마다 개념이 명확해진다.
`process(data)` -> `process_numbers(numbers)` -> `double_prices(prices)` -> `apply_inflation(prices)`. 각 단계마다 개념이 명확해진다.
Line 501: Line 134:

같은 이름, 다른 문맥:

{{{
# 문맥 1: 파일 시스템
class File:
    def size(self): # 파일 크기
        return self.bytes

# 문맥 2: 의류
class Shirt:
    def size(self): # 옷 사이즈
        return self.size_label # "M", "L"

# 문맥 3: 컬렉션
class List:
    def size(self): # 원소 개수
        return len(self.items)
}}}

`size()` 자체로는 애매하지만, 문맥이 의미를 만든다.
같은 `size()`라도 `File.size()`는 바이트 크기, `Shirt.size()`는 "M", "L", `List.size()`는 원소 개수를 의미한다. 문맥이 의미를 만든다.
Line 524: Line 137:

'''일관성 있는 형제들:'''

{{{
# ✅ CRUD 패턴
class UserRepository:
    def create(user):
        ...
    def read(user_id):
        ...
    def update(user):
        ...
    def delete(user_id):
        ...

# ✅ Validation 패턴
class Validator:
    def is_valid_email(email):
        ...
    def is_valid_password(password):
        ...
    def is_valid_username(username):
        ...
}}}
`UserRepository`의 `create`, `read`, `update`, `delete` 처럼 일관된 패턴은 예측 가능성을 만든다.
Line 550: Line 140:

실제 리팩토링 과정:

{{{
# 원본 코드
def func(x, y):
    z = []
    for i in x:
        if i > y:
            z.append(i)
    return z

# 1차: 의미 추가
def filter_data(data, threshold):
    result = []
    for item in data:
        if item > threshold:
            result.append(item)
    return result

# 2차: 도메인 언어
def filter_scores(scores, passing_grade):
    passing_scores = []
    for score in scores:
        if score >= passing_grade:
            passing_scores.append(score)
    return passing_scores

# 3차: 개념 명확화
def find_passing_students(scores, passing_grade=60):
    return [score for score in scores if score >= passing_grade]

# 최종: 더 나은 추상화
class GradeBook:
    def passing_students(self, cutoff=60):
        return [s for s in self.scores if s.grade >= cutoff]
}}}

이름이 진화하면서 설계도 진화했다.
엉성한 `func(x, y)` 로직을 `find_passing_students(scores, 60)`로 리팩토링하는 과정은 이름이 진화하면서 설계가 개선되는 전형적인 모습이다.
Line 591: Line 143:

'''은유가 만드는 직관:'''

{{{
# Factory 패턴 - "공장"
class UserFactory:
    def create(): # 공장에서 만든다
        ...

# Builder 패턴 - "건축가"
class QueryBuilder:
    def select(): # 선택
        ...
    def where(): # 조건
        ...
    def build(): # 건축 - 최종 완성
        ...

# Observer 패턴 - "관찰자"
class Subject:
    def attach(observer): # 관찰자를 붙인다
        ...
    def detach(observer): # 관찰자를 떼어낸다
        ...
    def notify(): # 관찰자에게 알린다
        ...
}}}

은유가 패턴을 이해 가능하게 만든다.
Factory(공장), Builder(건축가), Observer(관찰자) 등 디자인 패턴의 이름은 은유를 통해 복잡한 설계를 한 번에 이해시킨다.
Line 622: Line 146:

이름이 설계 문제를 드러낸다:

{{{
# ❌ 이름 짓기 어렵다 = 설계 문제
class UserManagerControllerHandlerService:
    def process_user_data_and_send_email_and_log():
        # 이 클래스는 무엇을 하는가?
        # 이 함수는 너무 많은 일을 한다!
        ...

# ✅ 이름이 쉬워지면 = 설계 개선됨
class UserRegistration:
    def register(self, user):
        self._validate(user)
        self._save(user)
        self._send_welcome_email(user)

class EmailService:
    def send_welcome(user):
        ...

class UserRepository:
    def save(user):
        ...
}}}

좋은 이름을 짓기 어렵다면, 설계를 다시 보라.
`UserManagerControllerHandlerService` 처럼 이름 짓기가 어렵다면, 그것은 클래스가 너무 많은 일을 하고 있다는 설계적 결함의 신호다.
Line 655: Line 152:

일반적인 것부터 시작하지 마라. 구체적인 것부터 시작하라.

{{{
# ❌ 너무 추상적부터
data → processed_data → result

# ✅ 구체적부터 시작
prices → doubled_prices → inflated_prices
}}}
일반적인 것부터 시작하지 마라. `prices` -> `doubled_prices` 처럼 구체적인 것부터 시작하라.
Line 667: Line 155:

이름을 먼저 짓지 말고, 사용하면서 이름을 발견하라.

{{{
# WorkingFirst와 연결
# 1. 일단 작동하게 (임시 이름)
def calc(x):
    return x * 1.1

# 2. 사용해보기
result = calc(price) # "price를 calc?" - 어색함

# 3. 더 나은 이름 발견
result = apply_tax(price) # 자연스러움!
}}}

사용 문맥이 좋은 이름을 제안한다.
이름을 먼저 짓지 마라. [[WorkingFirst]] 원칙에 따라 일단 작동하게 만들고, 사용 문맥 속에서 더 나은 이름을 발견하라.
Line 686: Line 158:

이름도 리팩토링 대상이다:

{{{
# 이해가 깊어지면 이름도 변한다
data # 초기: 뭔지 모름
user_data # 사용자 데이터라는 것 발견
preferences # 실제로는 선호도
settings # 더 정확하게는 설정
}}}

'''[[LivingVocabulary]]''' - 어휘는 진화한다.
이해도가 깊어지면 이름도 리팩토링하라. [[LivingVocabulary]] 패턴에 따라 어휘를 지속적으로 정제하라.
Line 700: Line 161:

이름을 소리내어 읽어보라:

{{{
# 읽어보기
order.calculate_total_amount()
# "Order야, calculate total amount 해줘"
# 어색함!

order.total()
# "Order의 total"
# 자연스러움!
}}}
이름을 소리 내어 읽어보라. "Order야, total 해줘"가 자연스러운지 확인하라.
Line 715: Line 164:

비슷한 개념은 비슷한 패턴으로:

{{{
# ✅ 일관된 패턴
user.is_active()
user.is_admin()
user.is_verified()

# ❌ 비일관적
user.is_active()
user.check_if_admin()
user.verified()
}}}
비슷한 개념은 비슷한 패턴으로 명명하여 일관성을 확인하라.
Line 734: Line 170:

명확하려다 장황해진다:

{{{
# ❌ 지나침
def calculateTotalAmountOfOrderIncludingTaxAndShipping():
    ...

# ✅ 문맥 활용
class Order:
    def total_with_tax_and_shipping(self):
        ...
    # 또는 더 간단히
    def total(self):
        return self.subtotal() + self.tax() + self.shipping()
}}}
명확하려다 장황해지는 것. 문맥을 활용하여 길이를 줄여라.
Line 752: Line 173:

약어는 이해를 방해한다:

{{{
# ❌ 약어 남용
def proc_usr_ord(u, o):
    ...

# ✅ 명확한 이름
def process_user_order(user, order):
    ...

# 예외: 보편적 약어는 OK
http_request # HTTP는 보편적
html_parser # HTML도 OK
id, url, api # 이들도 충분히 명확
}}}
`proc_usr_ord` 처럼 이해를 방해하는 약어를 피하라. 보편적인 약어(`id`, `url`)만 허용하라.
Line 771: Line 176:

같은 개념을 다른 이름으로:

{{{
# ❌ 혼란
class User:
    ...

class CustomerManager:
    ...

class ClientService:
    ...

# User? Customer? Client? 같은 건가 다른 건가?

# ✅ 일관성
class User:
    ...

class UserManager:
    ...

class UserService:
    ...
}}}

'''Ubiquitous Language''' - 하나의 개념은 하나의 이름으로.
`User`, `Customer`, `Client`를 혼용하지 마라. 하나의 개념은 하나의 이름으로 통일하라.
Line 801: Line 179:

타입 정보를 이름에 넣는다:

{{{
# ❌ Hungarian notation
strUserName = "John"
intUserAge = 30
arrUserOrders = []

# ✅ 의미에 집중
name = "John"
age = 30
orders = []
}}}

타입은 타입 시스템이 말하게 하라. 이름은 '''의미'''에 집중.
`strName`, `arrUsers` 처럼 타입 정보를 이름에 넣지 마라. 의미에 집중하라.
Line 819: Line 182:

의미 없는 단어들:

{{{
# ❌ 소음
class UserManager: # Manager가 뭘 하는지 불명확
class DataProcessor: # Processor가 뭘 하는지 불명확
class InfoHolder: # Holder가 무슨 의미?

# ✅ 구체적
class UserAuthenticator:
class OrderValidator:
class ConfigurationStore:
}}}

`Manager`, `Processor`, `Handler`, `Data`, `Info` - 이들은 종종 의미가 없다.
`Manager`, `Processor`, `Data` 처럼 의미 없는 단어(소음)를 제거하라.
Line 837: Line 185:

문맥 없이 이름을 평가한다:

{{{
# "get()이 좋은 이름인가?"
# → 판단 불가능!

# 문맥 제공:
user.get() # ❌ 무엇을 get?
user.email() # ✅ 명확
request.get() # ✅ HTTP GET (문맥상 명확)
}}}

항상 문맥에서 평가하라.
문맥 없이 이름을 평가하지 마라. `get()`이 좋은 이름인지는 그것이 어디에 속해 있느냐에 달렸다.
Line 855: Line 190:
=== Core Foundation ===

'''LanguageBuilding''' - 이름은 언어의 단어다. 좋은 이름이 모여 좋은 언어를 만든다. ''필수 관계''

'''MetaphorThinking''' - 은유와 비유가 직관적인 이름을 만든다. 이름을 통해 은유를 표현한다. ''인지적 도구''

'''TwoWorlds''' - 문제 공간과 해결 공간을 모두 잘 표현하는 이름. 도메인 언어 vs 기술 언어. ''두 종류의 이름''

'''DataAsFoundation''' - 데이터 구조의 이름이 전체 설계의 기반. 좋은 데이터 이름이 좋은 설계를 만든다. ''기반''

=== Design Process ===

'''WorkingFirst''' - 완벽한 이름부터 찾지 마라. 작동하는 코드를 먼저 만들고 이름은 점진적으로 개선. ''과정''

'''OrganicGrowth''' - 이름도 유기적으로 진화한다. 이해가 깊어지면 이름도 개선된다. ''진화''

'''LivingVocabulary''' - 어휘는 살아있고 성장한다. 이름도 프로젝트와 함께 발전한다. ''지속적 개선''

=== Code Quality ===

'''ComplexityTaming''' - 좋은 이름이 복잡성을 줄인다. 명확한 이름이 이해를 돕는다. ''단순화 도구''

'''ArtisanMind''' - 이름 짓기는 예술이다. 직관과 감각이 필요하다. ''장인 정신''

'''DirectPath''' - 좋은 이름이 코드의 흐름을 명확하게 만든다. ''명확성''

=== Team Collaboration ===

'''SharedMind''' - 공유된 어휘가 팀 협업을 만든다. 같은 이름으로 같은 개념을 이야기한다. ''공통 언어''

'''TechnicalCommunity''' - 일관된 네이밍 컨벤션이 커뮤니티를 만든다. ''규약''
 * '''[[LanguageBuilding]]''' - 이름은 언어의 단어입니다. 좋은 이름이 모여 좋은 언어를 만듭니다. ''필수 관계''
 * '''[[MetaphorThinking]]''' - 은유와 비유가 직관적인 이름을 만듭니다. ''인지적 도구''
 * '''[[TwoWorlds]]''' - 문제 공간과 해결 공간을 모두 잘 표현하는 이름이 필요합니다. ''균형''
 * '''[[DataAsFoundation]]''' - 데이터 구조의 이름이 전체 설계의 기반이 됩니다. ''기반''
 * '''[[WorkingFirst]]''' - 처음부터 완벽한 이름을 찾기보다 작동하는 코드에서 이름을 발견하십시오. ''순서''
 * '''[[LivingVocabulary]]''' - 이름은 고정된 것이 아니라 이해가 깊어짐에 따라 진화합니다. ''성장''
 * '''[[ArtisanMind]]''' - 이름을 짓는 것은 논리보다 뉘앙스가 중요한 장인의 기예입니다. ''기예''
Line 890: Line 200:
NamesAsDesign을 효과적으로 사용하고 있다는 신호:

'''주석이 줄어든다''' - 코드가 스스로 말한다. 이름만으로 의도가 명확하다.

'''새로운 팀원의 빠른 적응''' - 이름이 명확해서 코드베이스를 빠르게 이해한다.

'''코드 리뷰에서 이름 논의''' - "이 이름이 의도를 잘 표현하나요?" 같은 질문이 나온다.

'''일관된 어휘''' - 같은 개념을 항상 같은 이름으로 부른다. 혼란이 없다.

'''자연스러운 읽기''' - 코드를 읽으면 문장처럼 흘러간다.

'''쉬운 리팩토링''' - 이름을 바꾸면 설계 의도가 더 명확해진다.

'''도메인 대화''' - 도메인 전문가와 대화할 때 코드의 이름을 그대로 사용할 수 있다.


== For Teachers and Mentors ==

주니어의 네이밍을 개선하려면:

=== 문맥을 보여줘라 ===

"이 이름 좋아?"가 아니라 "이 이름이 여기서 어떻게 사용되는지 봐봐."

{{{
# 고립된 평가 X
def calc(x): ...

# 문맥에서 평가 ✓
order.calc() # 어색함
order.total() # 자연스러움
}}}

=== 소리내어 읽게 하라 ===

"이 코드를 영어 문장으로 읽어봐."

{{{
order.calculate_total_amount()
# → "Order, calculate total amount"
# 어색하지 않니?

order.total()
# → "Order's total"
# 자연스럽지?
}}}

=== 대안을 탐색하게 하라 ===

"한 가지 이름만 생각하지 말고, 3-4개 대안을 만들어봐."

{{{
Option 1: process_user_data()
Option 2: handle_user()
Option 3: authenticate_user()
Option 4: verify_credentials()

# 어느 것이 의도를 가장 잘 표현하나?
}}}

=== 리팩토링을 시연하라 ===

{{{
# "이름을 개선하면서 설계도 개선되는 것 봐봐"

# V1
def f(x):
    return x * 2

# V2
def process(data):
    return data * 2

# V3
def double(value):
    return value * 2

# V4
def apply_markup(price, rate=2.0):
    return price * rate
}}}

=== 패턴을 가르쳐라 ===

일관된 패턴:
 * Boolean: `is_*`, `has_*`, `can_*`
 * Collection: 복수형 `users`, `orders`
 * Factory: `create_*`, `build_*`, `make_*`
 * Query: `find_*`, `get_*`, `fetch_*`
 * 주석이 줄어들고 코드가 스스로 말한다.
 * 새로운 팀원이 코드베이스를 읽는 것만으로도 비즈니스 로직을 빠르게 파악한다.
 * 이름을 바꾸었을 뿐인데 클래스의 책임이 더 명확해지고 설계가 개선된다.
 * 도메인 전문가와 대화할 때 코드의 이름을 그대로 사용할 수 있다.
Line 984: Line 207:
Phil Karlton이 말했다: '''"There are only two hard things in Computer Science: cache invalidation and naming things."'''

Martin Fowler가 말했다: '''"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."'''

Ward Cunningham이 말했다: '''"Clean code reads like well-written prose."'''

Robert C. Martin이 말했다: '''"The ratio of time spent reading versus writing is well over 10 to 1... making it easy to read makes it easier to write."'''

이 모든 지혜는 같은 진리를 가리킨다:

{{{
이름은 코드의 가장 중요한 문서다.
이름은 설계의 표면이다.
이름은 개념 그 자체다.
}}}

=== Names as the Surface of Thought ===

코드를 작성할 때, 우리는 '''생각을 코드로 변환'''한다:

{{{
생각: "주문의 총액을 계산해야 해"

이름: calculate_order_total()

코드: def calculate_order_total(order): ...
}}}

이름은 '''생각의 표면'''이다. 생각이 명확하면 이름도 명확하다. 이름이 불명확하면 생각도 불명확하다.

=== Names as Design Decisions ===

모든 이름은 '''설계 결정'''이다:

 * `User` vs `Customer` - 도메인 모델 결정
 * `calculate()` vs `compute()` - 의도의 차이
 * `Manager` vs `Service` - 아키텍처 패턴
 * `data` vs `profile` - 추상화 레벨

이름을 바꾸는 것은 단순한 리네이밍이 아니다. '''설계를 바꾸는 것'''이다.

=== Names as Conversation ===

Eric Evans (DDD)의 '''Ubiquitous Language''':

{{{
"비즈니스 전문가가 사용하는 단어를 코드에서도 사용하라.
그러면 코드가 비즈니스를 말한다."
}}}

좋은 이름은:
 * 도메인 전문가와의 '''대화를 코드로''' 가져온다
 * 팀원들 사이의 '''공통 언어'''를 만든다
 * 미래의 개발자와 '''대화'''한다

=== The Paradox of Simplicity ===

역설: '''간단한 이름이 더 어렵다.'''

{{{
# 쉬움: 모든 것을 이름에
calculateTotalAmountOfOrderIncludingAllItemsAndTax()

# 어려움: 문맥과 조화
order.total()
}}}

간단한 이름을 짓는 것은 '''문맥을 이해하고 설계가 명확해야''' 가능하다.

좋은 이름은 쉬워 보이지만, 그 뒤에는 깊은 사고가 있다.


== Summary ==

NamesAsDesign는 '''이름을 설계 활동으로 보는 철학'''이다:

'''핵심 원칙:'''
 * '''이름은 문맥에서 평가''' - 고립된 이름은 판단 불가능
 * '''관계 속의 의미''' - 형제, 부모, 자식과 조화
 * '''이름 = 개념''' - 좋은 이름 = 좋은 개념화
 * '''이름 > 문서''' - 자체 문서화 코드
 * '''은유의 힘''' - 직관적 이해
 * '''의미 네트워크''' - 언어로서의 이름들

'''왜 작동하는가:'''
 * 이름은 생각의 표면
 * 이름은 설계 결정
 * 이름은 대화의 도구
 * 간단한 이름은 깊은 이해의 결과

'''주니어 vs 시니어:'''
 * 주니어: 이름을 라벨로 본다 → 너무 빠르거나 너무 장황함
 * 시니어: 이름을 설계로 본다 → 문맥에 맞고 관계 속에서 조화로운 이름

'''궁극의 통찰:'''
{{{
좋은 이름은 그 자체로 좋지 않다.
좋은 이름은 문맥 속에서 "잘 어울린다."
형제, 부모, 자식과 조화롭게.
문제 공간과 해결 공간을 모두 표현하면서.

이름 짓기가 어렵다면, 그것은 신호다:
개념이 불명확하거나, 설계가 잘못되었거나.

좋은 이름을 찾는 과정은
좋은 설계를 찾는 과정이다.
}}}

'''"Code is read much more often than it is written."'''

'''이름을 설계하라. 개념을 명확히 하라. 그러면 코드가 스스로 말할 것이다.'''
'''이름은 코드의 가장 중요한 문서이며, 설계의 표면이자 개념 그 자체입니다.'''

이름을 짓는 것은 단순한 라벨링이 아니라, 당신의 사유를 정제하는 설계 활동입니다. 좋은 이름을 찾기 어렵다면 설계를 다시 보십시오. 이름을 설계하십시오. 그러면 코드가 스스로 당신에게 진실을 말할 것입니다.

NamesAsDesign

주니어 개발자들을 위한 패턴 언어 - 네이밍을 설계 활동으로 다루어 개념을 명확히 하는 방법

The Story 1: The Search for the Right Name (Programming)

주니어 개발자 민수는 주문 처리 시스템을 작성하고 있었다. 그는 변수 이름을 짓다가 막혔다.

def process(data):
    x = data['items']
    y = 0
    for i in x:
        y += i['price'] * i['qty']
    return y

"이건 너무 못생겼어..." 민수는 생각했다. 30분 동안 고민한 끝에 이름을 아주 길게 고쳤다. calculate_order_total_amount_including_all_items(order_data). 하지만 코드 리뷰에서 하나가 말했다.

"민수님, 명확함은 길이가 아니라 문맥에서 나와요. 봐요."

class Order:
    def total(self):
        return sum(item.subtotal() for item in self.items)

class Item:
    def subtotal(self):
        return self.price * self.quantity

# 사용할 때
order = Order(...)
payment.charge(order.total())

"봐요, order.total()이라고 쓰면 Order의 total이라는 게 명확하죠? 문맥이 이름을 완성하는 거예요. 그리고 Item.subtotal()Item의 소계라는 게 바로 보이지요? 이름은 혼자 존재하는 게 아니라 관계 속에서 의미를 갖는 거예요. 이름 짓기는 단순히 라벨을 붙이는 게 아니라, 좋은 설계를 반영하는 설계 활동 그 자체입니다."

The Story 2: The Baby's Name (Ordinary Life)

민수와 하나는 곧 태어날 아기의 이름을 고민하고 있다.

민수의 작명 (The Functional Name): 민수는 실용적인 이름을 원한다. "우리 첫째니까 그냥 '민수 주니어 1호'라고 부르면 어때? 누가 봐도 내 아들인 걸 알 수 있잖아." 민수에게 이름은 단순히 대상을 식별하기 위한 라벨일 뿐이었다. 하지만 '1호'라는 이름은 아이의 개성이나 가족 안에서의 정체성을 전혀 담아내지 못했다.

하나의 작명 (The Design Name): 하나는 이름이 아이의 삶을 설계하는 첫 번째 단추라고 생각한다. "아이의 이름은 성(Last name)과 조화로워야 하고, 나중에 자라서 사회에서 불릴 때의 느낌도 고려해야 해." 하나는 아이가 평생 불릴 문맥을 상상하며 이름을 골랐다. "밝게 빛나라는 뜻의 '윤(潤)'을 넣자. 우리 가족의 따뜻한 분위기와도 잘 어울려." 이름이 정해지자 아이의 방을 어떻게 꾸밀지, 어떤 옷을 입힐지 같은 '설계'가 자연스럽게 뒤따랐다. 이름은 단순한 라벨이 아니라, 존재의 본질을 규정하는 설계의 시작임을 하나는 알고 있었다.

Context

당신은 코드를 작성하면서 변수, 함수, 클래스, 모듈에 이름을 붙여야 한다. 이름은 코드의 모든 곳에 있고, 코드를 읽는 사람이 가장 먼저 보는 것이다.

당신은 LanguageBuilding을 통해 도메인 언어를 만드는 것의 중요성을 알고, MetaphorThinking을 통해 은유가 이해를 돕는다는 것을 안다. 이제 그 언어를 구성하는 단어 하나하나를 만드는 단계다.

일상적인 상황:

  • 변수 이름을 data, temp, x 같은 일반적 이름으로 짓는다.

  • 함수 이름을 너무 길게 만든다 (calculateOrderTotalAmountIncludingTax).

  • 같은 개념을 여러 이름으로 부른다 (user / customer / account).

  • 이름을 짓는 데 과도한 시간을 쓰거나, 거의 생각 없이 짓는다.

Problem

초보 프로그래머는 네이밍을 단순한 라벨링으로 취급한다. 어떤 이는 너무 빨리 못생긴 이름을 붙이고, 어떤 이는 오래 고민하지만 결과는 여전히 좋지 않다.

The Naming Dichotomy

주니어는 두 극단 사이를 오간다:

  • 너무 빠른 네이밍: f(x), y = x['a'] 처럼 빠르지만 의미 없는 이름을 붙인다. 1주일 후 자신도 이해하지 못한다.

  • 너무 긴 네이밍: calculate_total_amount_of_order_including_all_line_items() 처럼 명확하려 했지만 장황하고 읽기 어려운 이름을 만든다.

The Fundamental Misunderstanding

Phil Karlton은 "컴퓨터 과학에서 어려운 것은 딱 두 가지뿐이다. 캐시 무효화와 이름 짓기"라고 했다. 왜 네이밍이 어려운가?

  • 잘못된 믿음: "좋은 이름은 그 자체로 명확해야 한다", "길고 자세할수록 좋다."

  • 진실: 이름 자체로는 좋고 나쁨을 판단할 수 없다. 문맥에 embedding되었을 때 평가할 수 있다. 관계 속에서 의미가 만들어지기 때문이다.

The Isolation Problem

주니어는 이름을 고립되어 생각한다. 하지만 이름은 관계망 속에 존재한다. order.total()이라고 쓰면 'Order'라는 부모가 문맥을 제공하기 때문에 짧은 이름으로도 충분히 명확해진다. 이름의 품질은 부모, 형제, 자식과의 관계 속에서 결정된다.

The Surface of Design

이름은 설계의 표면이다. 나쁜 이름은 종종 나쁜 설계를 반영한다. 이름 짓기가 어렵다는 것은 개념이 불명확하거나, 책임이 잘못 분배되었거나, 추상화가 잘못되었다는 신호다.

Name as Concept

이름은 단순한 라벨이 아니라 개념 그 자체다. itemsshopping_cart라고 부르는 순간, 단순한 리스트가 쇼핑이라는 맥락을 가진 개념으로 변한다. 이름을 바꾸면 생각이 바뀐다.

Names vs Documentation

좋은 이름은 주석보다 가치 있다. "Clean code is when each function does pretty much what you expected." (Ward Cunningham). 그 예상을 만드는 것이 바로 이름이다.

Solution

네이밍을 사고를 명확하게 하고 추상화를 드러내는 설계 활동으로 다뤄라. 좋은 이름은 문맥 속에서 평가되고, 관계 속에서 의미를 갖는다. 이름은 개념이고, 좋은 이름은 좋은 설계를 반영한다.

Principle 1: Names in Context (Embedding)

이름은 고립되어 평가할 수 없다. 문맥에 embedding하여 평가하라.

  • Small Context (함수 내부): 짧은 스코프에서는 total, items 처럼 짧은 이름이 명확하다.

  • Large Context (클래스, 모듈): Order.total() 처럼 클래스 이름이 문맥을 제공할 때 메서드 이름은 간결해질 수 있다.

Principle 2: Relational Quality (Playing Along)

좋은 이름은 "잘 어울린다" - 형제, 부모, 자식과 조화롭게.

  • Siblings (형제 관계): 같은 레벨의 이름들은 일관된 패턴을 따라야 한다 (name(), age(), email()).

  • Parent-Child (부모-자식 관계): 부모와 자식이 조화로워야 한다. OrderCalculator.calculate_order_total()은 중복이다. Order.total()이 더 자연스럽다.

Principle 3: Two Spaces - Problem and Solution

TwoWorlds를 기억하라. 좋은 이름은 문제 공간과 해결 공간을 모두 잘 표현한다.

  • Problem Space Names (도메인 언어): Order.place(), Customer.purchase() 처럼 비즈니스 전문가와 공유하는 보편 언어(Ubiquitous Language)를 사용하라.

  • Solution Space Names (기술 언어): OrderRepository, EventBus 처럼 기술적 패턴은 기술 용어로 표현하라.

Principle 4: Name as Concept (Conceptualization)

이름 짓기는 개념화하기다. 명확한 이름 = 명확한 개념. 이름을 찾는 과정은 개념을 발견하는 과정이다. data -> user_data -> user_profile로 이름이 명확해지는 과정은 설계가 정교해지는 과정과 일치한다.

Principle 5: Names > Documentation

좋은 이름은 주석을 불필요하게 만든다. "The proper use of comments is to compensate for our failure to express ourselves in code." (Robert C. Martin). 이름으로 표현하지 못해서 주석을 쓰는 것이다.

Principle 6: Metaphor and Analogy

MetaphorThinking - 좋은 은유는 좋은 이름을 만든다. Stack.push(), Queue.enqueue(), Stream.flush() 처럼 은유가 직관적 이해를 돕는다.

Principle 7: Semantic Network

LanguageBuilding - 이름들은 의미 네트워크를 형성한다. total, subtotal, tax - 이 단어들은 서로 관계를 형성하며 하나를 보면 다른 것을 예상할 수 있게 한다.

Real Examples

Example 1: From Generic to Specific

process(data) -> process_numbers(numbers) -> double_prices(prices) -> apply_inflation(prices). 각 단계마다 개념이 명확해진다.

Example 2: Context Makes Meaning

같은 size()라도 File.size()는 바이트 크기, Shirt.size()는 "M", "L", List.size()는 원소 개수를 의미한다. 문맥이 의미를 만든다.

Example 3: Siblings Harmony

UserRepositorycreate, read, update, delete 처럼 일관된 패턴은 예측 가능성을 만든다.

Example 4: Real Naming Session

엉성한 func(x, y) 로직을 find_passing_students(scores, 60)로 리팩토링하는 과정은 이름이 진화하면서 설계가 개선되는 전형적인 모습이다.

Example 5: Metaphor Power

Factory(공장), Builder(건축가), Observer(관찰자) 등 디자인 패턴의 이름은 은유를 통해 복잡한 설계를 한 번에 이해시킨다.

Example 6: Names Reveal Design Issues

UserManagerControllerHandlerService 처럼 이름 짓기가 어렵다면, 그것은 클래스가 너무 많은 일을 하고 있다는 설계적 결함의 신호다.

The Naming Process

Process 1: Start Concrete, Then Abstract

일반적인 것부터 시작하지 마라. prices -> doubled_prices 처럼 구체적인 것부터 시작하라.

Process 2: Let Context Emerge

이름을 먼저 짓지 마라. WorkingFirst 원칙에 따라 일단 작동하게 만들고, 사용 문맥 속에서 더 나은 이름을 발견하라.

Process 3: Refactor Names

이해도가 깊어지면 이름도 리팩토링하라. LivingVocabulary 패턴에 따라 어휘를 지속적으로 정제하라.

Process 4: Read Aloud Test

이름을 소리 내어 읽어보라. "Order야, total 해줘"가 자연스러운지 확인하라.

Process 5: Consistency Check

비슷한 개념은 비슷한 패턴으로 명명하여 일관성을 확인하라.

Common Pitfalls

Pitfall 1: Premature Long Names

명확하려다 장황해지는 것. 문맥을 활용하여 길이를 줄여라.

Pitfall 2: Abbreviations

proc_usr_ord 처럼 이해를 방해하는 약어를 피하라. 보편적인 약어(id, url)만 허용하라.

Pitfall 3: Inconsistent Vocabulary

User, Customer, Client를 혼용하지 마라. 하나의 개념은 하나의 이름으로 통일하라.

Pitfall 4: Type in Name

strName, arrUsers 처럼 타입 정보를 이름에 넣지 마라. 의미에 집중하라.

Pitfall 5: Noise Words

Manager, Processor, Data 처럼 의미 없는 단어(소음)를 제거하라.

Pitfall 6: Naming in Isolation

문맥 없이 이름을 평가하지 마라. get()이 좋은 이름인지는 그것이 어디에 속해 있느냐에 달렸다.

Connection to Other Patterns

  • LanguageBuilding - 이름은 언어의 단어입니다. 좋은 이름이 모여 좋은 언어를 만듭니다. 필수 관계

  • MetaphorThinking - 은유와 비유가 직관적인 이름을 만듭니다. 인지적 도구

  • TwoWorlds - 문제 공간과 해결 공간을 모두 잘 표현하는 이름이 필요합니다. 균형

  • DataAsFoundation - 데이터 구조의 이름이 전체 설계의 기반이 됩니다. 기반

  • WorkingFirst - 처음부터 완벽한 이름을 찾기보다 작동하는 코드에서 이름을 발견하십시오. 순서

  • LivingVocabulary - 이름은 고정된 것이 아니라 이해가 깊어짐에 따라 진화합니다. 성장

  • ArtisanMind - 이름을 짓는 것은 논리보다 뉘앙스가 중요한 장인의 기예입니다. 기예

Signs of Success

  • 주석이 줄어들고 코드가 스스로 말한다.
  • 새로운 팀원이 코드베이스를 읽는 것만으로도 비즈니스 로직을 빠르게 파악한다.
  • 이름을 바꾸었을 뿐인데 클래스의 책임이 더 명확해지고 설계가 개선된다.
  • 도메인 전문가와 대화할 때 코드의 이름을 그대로 사용할 수 있다.

The Ultimate Insight

이름은 코드의 가장 중요한 문서이며, 설계의 표면이자 개념 그 자체입니다.

이름을 짓는 것은 단순한 라벨링이 아니라, 당신의 사유를 정제하는 설계 활동입니다. 좋은 이름을 찾기 어렵다면 설계를 다시 보십시오. 이름을 설계하십시오. 그러면 코드가 스스로 당신에게 진실을 말할 것입니다.


CategoryPatternLanguage CategoryProgramming CategoryDesign CategoryNaming CategoryCleanCode

NamesAsDesign (last edited 2025-12-30 09:07:55 by 정수)