"매 OO 언어에서 다른 코드 변경 없이 동작을 바꿀 수 있는 분기점 — 매 polymorphism이 enabling point.". Michael Feathers의 Working Effectively with Legacy Code (2004) 에서 정의된 3개 seam (preprocessing, link, object) 중 가장 강력. 2026 현재 mock framework · DI container의 핵심 메커니즘.
Introducing seam to legacy code (Extract Interface)
// Before: hard dependency on concrete classpublicclassReport{publicvoidgenerate(){vardb=newMySQLConnection();// ← no seam// ...}}// After: introduced object seampublicclassReport{privatefinalDatabasedb;publicReport(Databasedb){this.db=db;}publicvoidgenerate(){/* uses db */}}publicinterfaceDatabase{ResultSetquery(Stringsql);}publicclassMySQLConnectionimplementsDatabase{/* ... */}
Testing legacy code with subclass-and-override
publicclassLegacyService{publicReportrun(){vardata=fetchData();// ← protected, override in testreturnprocess(data);}protectedDatafetchData(){/* real network */}}// TestclassTestableServiceextendsLegacyService{@OverrideprotectedDatafetchData(){returnData.fixture();}}
매 결정 기준
상황
Approach
New code, OO language
Constructor injection + interface
Legacy class, can't refactor much
Extract Interface + DI
Sealed legacy class
Subclass and Override Method
C/C++ no virtual overhead
Link seam (selective compilation)
Functional language
Higher-order function = seam
기본값: interface + constructor injection — 매 가장 explicit · testable.