Files
2nd/10_Wiki/Topics/Architecture/Preserve Whole Object (객체 통째로 넘기기).md
T
2026-05-10 22:08:15 +09:00

4.7 KiB
Raw Blame History

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-preserve-whole-object-객체-통째로-넘기기 Preserve Whole Object (객체 통째로 넘기기) 10_Wiki/Topics verified self
Preserve Whole Object
객체 통째로 넘기기
pass whole object
none A 0.9 applied
refactoring
code-smell
parameter-list
fowler
2026-05-10 pending
language framework
python-typescript refactoring

Preserve Whole Object (객체 통째로 넘기기)

매 한 줄

"매 여러 field를 매 풀어 넘기지 말고 매 객체 자체를 넘겨라". Preserve Whole Object은 Fowler "Refactoring" (1999, 2nd ed. 2018) 의 매 catalog refactoring — 매 호출자가 매 객체에서 매 여러 값을 매 추출해 매 인자로 넘기는 매 패턴을 매 객체 통째로 매 넘기는 매 형태로 매 변환. 매 parameter list 축소 + 매 의존성 명시화.

매 핵심

매 적용 trigger

  • 매 호출자가 매 한 객체에서 매 3+ 값을 매 추출해 매 인자로 넘김.
  • 매 같은 추출 패턴이 매 여러 callsite에서 매 반복.
  • 매 추후 다른 field가 매 필요해질 때 매 signature 변경 비용.

매 Trade-off

  • 장점: parameter list 축소, 매 future-proof, 매 객체 의존성 명시.
  • 단점: 매 callee의 매 객체 의존도 증가, 매 testability 저하 가능 (큰 객체 mock).
  • 언제 X: 매 callee가 매 domain 외부 (해당 객체 unknown), 매 12 field만 사용.

매 응용

  1. Range comparison: inRange(low, high)inRange(range).
  2. Validation: validate(name, email, age)validate(user).
  3. Pricing: quote(item.price, item.tax, item.discount)quote(item).

💻 패턴

Before / After (Python)

# 매 Before — primitive obsession + parameter explosion
def is_within(low: float, high: float, value: float) -> bool:
    return low <= value <= high

low, high = room.days_temp_range.low, room.days_temp_range.high
if is_within(low, high, today.low) and is_within(low, high, today.high):
    alert()

# 매 After — preserve whole object
def is_within(rng: "Range", value: float) -> bool:
    return rng.low <= value <= rng.high

if room.range.contains(today.low) and room.range.contains(today.high):
    alert()

Method extraction onto the object

@dataclass(frozen=True)
class Range:
    low: float
    high: float
    def contains(self, v: float) -> bool: return self.low <= v <= self.high
    def overlaps(self, o: "Range") -> bool:
        return self.low <= o.high and o.low <= self.high

Validation refactor

# Before
def validate_user(name: str, email: str, age: int, country: str): ...

# After
@dataclass
class UserDraft:
    name: str; email: str; age: int; country: str

def validate_user(u: UserDraft): ...

TypeScript variant

// 매 Before
function quote(price: number, tax: number, discount: number) { ... }

// 매 After
interface PricedItem { price: number; tax: number; discount: number; }
function quote(item: PricedItem) { ... }

IDE refactoring (PyCharm/IntelliJ)

1. Extract Class → 매 Range (low, high).
2. Move Method → contains() onto Range.
3. Inline Variable → low, high at callsite.
4. Replace Parameter with Method Call → is_within(range, value).

매 결정 기준

상황 Approach
3+ field 매 같은 객체에서 추출 Preserve Whole Object
12 field만 사용 매 raw param OK
Cross-context call (객체 unknown) 매 raw param + DTO
Hot loop, 매 객체 매 large 매 individual primitive (perf)

기본값: 3+ field 매 reuse 시 매 객체 통째로.

🔗 Graph

🤖 LLM 활용

언제: 매 long parameter list refactor, 매 API surface 정리. 언제 X: 매 cross-process boundary (DTO/serialization 고려).

안티패턴

  • 매 God object 통째로 넘김: 매 너무 큰 객체 매 의존성 폭발.
  • 매 Mock hell: 매 unit test 시 매 모든 field 매 mock.
  • 매 Stale DTO: 매 object 와 매 DTO 매 분리 안 해 매 layer leak.
  • 매 매 통째 매 무비판적용: 매 1 field만 사용해도 매 객체 통째로.

🧪 검증 / 중복

  • Verified (Fowler "Refactoring" 2nd ed. 2018, ch. 11 "Preserve Whole Object").
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — Fowler refactoring + before/after Python/TS