데코레이터 패턴 정의
파생클래스의 생성자 파라미터에 덮어씌우고자 하는 인스턴스를 매개변수로 넣음으로써 재귀적으로 현재 인스턴스의 상태를 추가하는 방법이다.
필요한 상황
1. Open-Closed-Principle(OCP) 원칙을 지키면서 인스턴스의 현재 상태를 추가하고 싶을 때
2. 인스턴스의 상태를 자유롭게 누적시키는 로직이 필요할 때
Class 다이어그램
코드
1. Pizza class 코드
public abstract class Pizza
{
protected string? strDescription;
public abstract String getDescription();
public abstract double cost();
}
2. Topping class 코드
public abstract class Topping : Pizza
{
public override String getDescription() => this.strDescription;
}
3. Pizza class의 파생 코드
public class CheesePizza : Pizza
{
public CheesePizza()
{
base.strDescription = "CheesePizza";
}
public override double cost()
{
return 2.33;
}
public override string getDescription()
{
return base.strDescription;
}
}
public class MeatLoverPizza : Pizza
{
public MeatLoverPizza()
{
base.strDescription = "MeatLoverPizza";
}
public override double cost()
{
return 3.5;
}
public override string getDescription()
{
return base.strDescription;
}
}
4. Topping class의 파생 코드
public class CheeseTopping : Topping
{
Pizza pizza;
public CheeseTopping(Pizza pizza)
{
this.pizza = pizza;
}
public override double cost() => (pizza.cost() + 0.5);
public override String getDescription() => (pizza.getDescription() + " CheeseTopping");
}
public class TomatoTopping : Topping
{
Pizza pizza;
public TomatoTopping(Pizza pizza)
{
this.pizza = pizza;
}
public override double cost() => this.pizza.cost() + 0.2;
public override String getDescription() => this.pizza.getDescription() + " Tomato Topping";
}
5. main 코드
Pizza pizza = new CheesePizza();
Console.WriteLine($"{pizza.getDescription()} : {pizza.cost()}");
pizza = new CheeseTopping(pizza);
Console.WriteLine($"{pizza.getDescription()} : {pizza.cost()}");
pizza = new CheeseTopping(pizza);
Console.WriteLine($"{pizza.getDescription()} : {pizza.cost()}");
pizza = new TomatoTopping(pizza);
Console.WriteLine($"{pizza.getDescription()} : {pizza.cost()}");
코드 설명
1. Pizza class는 파생 클래스 모두 공통으로 사용할 클래스이다.
2. Topping class 는 Pizza class의 파생 클래스이다. Topping class는 계속 이전 인스턴스를 인자로 받아서 추가로 데이터를 추가한다.
3. CheesePizza, MeatLoverPizza class들은 Pizza class의 파생 클래스로써 기본 Pizza의 대분류로 나눈 것이다. 그 이상 그 이하도 없다.
4. Cheese Topping, Tomato Topping class들은 Topping class의 파생 클로스로써 중요한 점은 Pizza class의 인스턴스를 생성자에서 받아서 이전 상태의 인스턴스를 저장한다. 저장한 인스턴스는 다음 함수 호출 시 사용한다. 이는 결국 재귀적으로 내부 Pizza class의 인스턴스를 재귀적으로 호출하는 역할을 수행하게 된다.
5. 사용하는 코드이다.
설명 보충을 위한 그림 자료
클래스 다이어그램 하단에 별도 기입..
필요에 따라 추가 설명
딱히 어려운 건 없다.
정리 및 결론
데코레이터 패턴도 다양한 언어, API에서 제공하는 패턴 중 하나이다. 하지만 재귀함수적 특징으로 인해 코드의 가독성이 떨어지는 단점이 있다. 사용할지 말지는 본인 판단!!
'Program > SW Design Patterns' 카테고리의 다른 글
CH7 어댑터&퍼사드 패턴 (0) | 2023.03.19 |
---|---|
CH6 커맨드 패턴 (0) | 2023.03.07 |
CH4 팩토리 패턴 (0) | 2023.03.04 |
CH3 옵저버 패턴 (0) | 2023.03.03 |
CH2 싱글턴 패턴 (0) | 2023.03.02 |