"매 null check 의 polymorphism 으로 대체". Fowler 의 Refactoring 카탈로그 entry — if (x == null) scattered checks 를 default-behavior object 로 collapse. 2026 modern 에서는 Optional/Maybe monad, sealed class hierarchy, TypeScript discriminated union 으로 evolve 했지만 core idea 는 동일.
매 핵심
매 문제
Repeated null guards: customer == null ? "unknown" : customer.name() 의 매 caller 마다 반복.
Null-aware logic 의 매 client code 에 leak — encapsulation violation.
NullPointerException / undefined error 의 매 production crash 의 top cause.
매 solution
Null state 를 dedicated subclass 로 represent: NullCustomer extends Customer.
Default behavior 를 polymorphic method 로 push down.
Caller 는 customer.name() 의 null check 없이 호출.
매 응용
Fowler refactoring step-by-step (Replace Conditional with Polymorphism 의 sibling).
Domain-driven design 의 missing aggregate handling.
typeMaybe<T>={kind:"some";value: T}|{kind:"none"};constcustomer: Maybe<Customer>=loadCustomer(id);constname=customer.kind==="some"?customer.value.name:"occupant";// Or with helper
functionfold<T,R>(m: Maybe<T>,onSome:(v: T)=>R,onNone:()=>R):R{returnm.kind==="some"?onSome(m.value):onNone();}
interfaceLogger{log(msg: string):void;}classConsoleLoggerimplementsLogger{log(msg: string){console.log(msg);}}classNullLoggerimplementsLogger{log(_msg: string){/* no-op */}}classService{constructor(privatelogger: Logger=newNullLogger()){}// 매 logger null check 없이 항상 호출 가능
}
7. React/UI default component
functionUserBadge({user}:{user: User|null}){// 매 null branch 없이 — NullUser component 로 dispatch
constu=user??NULL_USER;return<span>{u.displayName}</span>;}constNULL_USER: User={id:"anonymous",displayName:"Anonymous",avatar:"/default.png",};
매 결정 기준
상황
Approach
OO codebase, 매 null check 의 3+ 위치 반복
Null Object class.
Functional / TS strict, 매 type-level safety 필요
Maybe / Optional / discriminated union.
Side-effect 의 default no-op (logger, audit)
NullLogger 의 dependency injection.
매 distinct missing-state semantics (unknown vs deceased)
Special Case (multiple null subtypes).
매 single-use null check
매 그냥 inline ?? default.
기본값: TypeScript / modern stack 에서는 ?? default 또는 discriminated union. OO heavy refactor target 에서는 Null Object class.
언제: legacy codebase 의 null-check noise 제거 refactor, library API 의 default behavior design.
언제 X: 매 single null check, performance-critical hot path (allocation overhead), exception 이 의도된 signal 인 경우.
❌ 안티패턴
Hidden bugs: NullCustomer 의 silent default 가 매 real bug 를 mask. Logging 또는 isNull() flag 로 trace 가능하게 유지.
God Null Object: 매 모든 method 에 default 의 over-design. 매 진짜 polymorphic 사용처만 cover.
Equality confusion: nullCustomer === null false 의 매 caller 혼란. 매 명확한 documentation + isNull() helper.
Mutation on Null Object: 매 shared instance 의 mutation 이 cross-contamination 의 cause. 매 immutable 유지.
🧪 검증 / 중복
Verified (Fowler, Refactoring 2nd ed., "Introduce Special Case" — Null Object 의 modern rename).
신뢰도 A.
🕓 Changelog
날짜
변경
2026-05-08
Phase 1
2026-05-10
Manual cleanup — Null Object refactoring + modern Maybe/sealed union variants