"매 duplicated method 매 sibling subclasses 안 — 매 superclass 로 hoist". Fowler의 Refactoring (1999, 2nd ed 2018) 매 catalog item. 매 Extract Superclass / Replace Inheritance with Delegation 와 매 짝.
매 핵심
매 trigger
매 두 개 이상 sibling subclass 가 매 identical (or near-identical) method body 보유.
매 fields 도 같이 pull up 가능 — Pull Up Field.
매 constructor body 도 — Pull Up Constructor Body.
매 mechanics
매 step 1: 매 method bodies 매 inspect — 매 truly identical 인지.
매 step 2: 매 differences 매 parameterize — 매 identical 로 만들기.
매 step 3: 매 superclass 매 method 작성, 매 subclasses 매 method 삭제.
매 step 4: 매 test — 매 polymorphic dispatch 매 correct 인지.
매 응용
ORM entity hierarchy — 매 BaseEntity 매 id, createdAt pull up.
UI component class hierarchy — 매 common rendering logic.
fromabcimportABCclassShape(ABC):defdescribe(self)->str:returnf"Shape with area {self.area():.2f}"classCircle(Shape):def__init__(self,r):self.r=rdefarea(self):return3.14159*self.r**2classSquare(Shape):def__init__(self,s):self.s=sdefarea(self):returnself.s**2
TypeScript — abstract class
abstractclassAnimal{constructor(protectedname: string){}describe():string{// pulled up from Dog/Cat
return`${this.name} is a ${this.constructor.name}`;}abstractmakeSound():string;}classDogextendsAnimal{makeSound() {return"Woof";}}classCatextendsAnimal{makeSound() {return"Meow";}}
Refactoring with parameterization
// Before — almost identicalclassA{intcharge(){returnbase*1.05;}}classB{intcharge(){returnbase*1.10;}}// Step: parameterizeclassAextendsBilling{intcharge(){returncalc(1.05);}}classBextendsBilling{intcharge(){returncalc(1.10);}}// Pull upclassBilling{protectedintcalc(doublerate){returnbase*rate;}}
매 결정 기준
상황
Approach
매 identical method 매 2+ sibling
Pull Up Method
매 similar but different method
Form Template Method 먼저
매 only 1 subclass uses
Don't pull up
매 deep inheritance (>3 levels)
Composition 고려
매 LSP 위반 risk
Don't — Extract Class instead
기본값: 매 2+ siblings 매 identical body — Pull Up. 매 그 외 — composition.
언제: 매 sibling classes 매 duplication detection — LLM 매 structural similarity 매 잘 detect. 매 IDE refactor (IntelliJ, Rider) 매 mechanical transform 자동.
언제 X: 매 cross-cutting concern (logging, auth) — Pull Up 대신 매 aspect / decorator.
❌ 안티패턴
Forced inheritance: 매 unrelated classes 매 method 공유 위해 매 fake superclass — composition 사용.
God superclass: 매 너무 많이 pull up — base class 가 매 dumping ground 가 됨.
LSP violation: 매 pulled-up method 가 매 some subclass 에서 매 invalid — split.