π‘ λ°μ½λ μ΄ν°(Decorator) ν¨ν΄μ΄λ?
λμ κ°μ²΄μ λν κΈ°λ₯ νμ₯μ΄λ λ³κ²½μ΄ νμν λ κ°μ²΄μ κ²°ν©(μλ‘μ΄ νλμ ν¬ν¨ν νΉμ λνΌ κ°μ²΄λ€ λ΄μ μΆκ°)μ ν΅ν΄ μλΈν΄λμ± λμ μΈ μ μλ ꡬ쑰μ λμμΈ ν¨ν΄μ λλ€.
λ°μ½λ μ΄ν° ν¨ν΄μ μ΄μ©νλ©΄ νμν μΆκ° κΈ°λ₯μ μ‘°ν©μ λ°νμμμ λμ μΌλ‘ μμ±ν μ μμ΅λλ€. λμ κ°μ²΄λ₯Ό μλ‘μ΄ νλλ€μ ν¬ν¨ν λ°μ½λ μ΄ν° κ°μ²΄μ λ£μ΄μ νλλ€μ ν΄λΉ μ₯μμ κ°μ²΄λ§λ€ μ°κ²°μν΅λλ€. μλΈν΄λμ€λ‘ ꡬμ±ν λ λ³΄λ€ ν¨μ¬ μ μ°νκ² κΈ°λ₯μ νμ₯ ν μ μκ³ , κΈ°λ₯μ ꡬννλ ν΄λμ€λ€μ λΆλ¦¬ν¨μΌλ‘μ¨ μμ μ΄ μ©μ΄ν΄μ§λλ€.
π‘ ν΄λμ€ λ€μ΄μ΄κ·Έλ¨μΌλ‘ λ³Έ λ°μ½λ μ΄ν° ν¨ν΄
- Component : μλ³Έ κ°μ²΄μ μ₯μλ κ°μ²΄ λͺ¨λλ₯Ό λ¬Άλ μν .
- Concrete Component : μλ³Έ κ°μ²΄. (λ°μ½λ μ΄ν ν κ°μ²΄ = λνλλ κ°μ²΄)
- Base Decorator : μΆμνλ λ°μ½λ μ΄ν° ν΄λμ€. μλ³Έ κ°μ²΄λ₯Ό ν©μ±(composition)ν wrappee νλμ μΈν°νμ΄μ€μ ꡬν λ©μλλ₯Ό κ°μ§κ³ μμ΅λλ€.
- Concrete Decorator : ꡬ체μ μΈ λ°μ½λ μ΄ν° ν΄λμ€. λΆλͺ¨ ν΄λμ€κ° κ°μΈκ³ μλ νλμ Componentλ₯Ό νΈμΆνλ©΄μ νΈμΆ μ /νλ‘ λΆκ°μ μΈ λ‘μ§μ μΆκ°ν μ μμ΅λλ€.
π‘ λ°μ½λ μ΄ν° ν¨ν΄ ꡬν
// μλ³Έ κ°μ²΄μ μ₯μλ κ°μ²΄ λͺ¨λλ₯Ό λ¬Άλ μΈν°νμ΄μ€
interface IComponent {
void operation();
}
// μ₯μλ μλ³Έ κ°μ²΄
class ConcreteComponent implements IComponent {
public void operation() {
}
}
// μ₯μμ μΆμ ν΄λμ€
abstract class Decorator implements IComponent {
IComponent wrappee; // μλ³Έ κ°μ²΄λ₯Ό composition
Decorator(IComponent component) {
this.wrappee = component;
}
public void operation() {
wrappee.operation(); // μμ
}
}
// μ₯μμ ν΄λμ€
class ComponentDecorator1 extends Decorator {
ComponentDecorator1(IComponent component) {
super(component);
}
public void operation() {
super.operation(); // μλ³Έ κ°μ²΄λ₯Ό μμ ν΄λμ€μ μμμ ν΅ν΄ μ€ννκ³
extraOperation(); // μ₯μ ν΄λμ€λ§μ λ©μλλ₯Ό μ€ννλ€.
}
void extraOperation() {
}
}
class ComponentDecorator2 extends Decorator {
ComponentDecorator2(IComponent component) {
super(component);
}
public void operation() {
super.operation(); // μλ³Έ κ°μ²΄λ₯Ό μμ ν΄λμ€μ μμμ ν΅ν΄ μ€ννκ³
extraOperation(); // μ₯μ ν΄λμ€λ§μ λ©μλλ₯Ό μ€ννλ€.
}
void extraOperation() {
}
}
public class Client {
public static void main(String[] args) {
// 1. μλ³Έ κ°μ²΄ μμ±
IComponent obj = new ConcreteComponent();
// 2. μ₯μ 1 νκΈ°
IComponent deco1 = new ComponentDecorator1(obj);
deco1.operation(); // μ₯μλ κ°μ²΄μ μ₯μλ κΈ°λ₯ μ€ν
// 3. μ₯μ 2 νκΈ°
IComponent deco2 = new ComponentDecorator2(obj);
deco2.operation(); // μ₯μλ κ°μ²΄μ μ₯μλ κΈ°λ₯ μ€ν
// 4. μ₯μ 1 + 2 νκΈ°
IComponent deco3 = new ComponentDecorator1(new ComponentDecorator2(obj));
}
}
π‘ λ§λ¬΄λ¦¬
λ°μ½λ μ΄ν° ν¨ν΄μ
- κ°μ²΄ μ± μκ³Ό νλμ΄ λμ μΌλ‘ μν©μ λ°λΌ λ€μν κΈ°λ₯μ΄ λΉλ²νκ² μΆκ°/μμ λ λ
- κ°μ²΄μ κ²°ν©μ ν΅ν΄ κΈ°λ₯μ΄ μμ±λ μ μμ λ
- κ°μ²΄λ₯Ό μ¬μ©νλ μ½λλ₯Ό μμμν€μ§ μκ³ λ°νμμ κ°μ²΄μ μΆκ° λμμ ν λΉν μ μμ΄μΌ ν λ
- μμμ ν΅ν΄ μλΈν΄λμ±μΌλ‘ κ°μ²΄μ λμμ νμ₯νλ κ²μ΄ μ΄μνκ±°λ λΆκ°λ₯ ν λ
μ μ¬μ©ν μ μμ΅λλ€.
λ°μ½λ μ΄ν° ν¨ν΄μ μ¬μ©νλ©΄ λ°νμμ κ°μ²΄λ€μμλΆν° μ± μλ€μ μΆκ°νκ±°λ μ κ±°ν μ μκ³ , κ°μ²΄λ₯Ό μ¬λ¬ λ°μ½λ μ΄ν°λ‘ λννμ¬ μ¬λ¬ νλλ€μ ν©μ±ν μ μμ΅λλ€.
κ° μ₯μμ ν΄λμ€λ§λ€ κ³ μ μ μ± μμ κ°μ§κ³ (SRP μ€μ), ν΄λΌμ΄μΈνΈ μ½λ μμ μμ΄ κΈ°λ₯ νμ₯μ΄ νμνλ©΄ μ₯μμ ν΄λμ€λ₯Ό μΆκ°νλ©΄ λ©λλ€.(OCP μ€μ) λν, ꡬνμ²΄κ° μλ μΈν°νμ΄μ€λ₯Ό λ°λΌλ³΄λ ꡬ쑰λ‘, DIPλ₯Ό λ§μ‘±ν©λλ€.