Decorator Pattern이란?
Decorator Pattern은 객체의 기능을 동적으로 확장하기 위한 디자인 패턴입니다. 객체의 기능을 유연하게 확장하면서도 기존 코드의 수정 없이 구현할 수 있습니다. 이 패턴은 객체 지향 디자인 원칙 중 하나인 개방-폐쇄 원칙(Open-Closed Principle)을 준수합니다. 이 원칙은 기능 확장에 대해 개방되어 있으나, 수정에 대해 폐쇄되어 있어야 한다는 것입니다. Decorator Pattern은 이 원칙을 따르면서도 객체의 기능 확장을 가능하게 합니다.
객체 기능 동적 확장을 위한 디자인 패턴
Decorator Pattern은 객체의 기능을 동적으로 확장할 때 유용합니다. 이 패턴은 객체에 새로운 기능을 추가하고자 할 때, 기존 코드의 수정 없이 새로운 기능을 추가할 수 있도록 합니다. 이를 위해, Decorator 클래스를 사용합니다.
Decorator 클래스는 객체를 래핑하고, 래핑된 객체의 기능을 확장합니다. 실제로 사용되는 객체와 동일한 인터페이스를 구현합니다. Decorator 클래스는 생성자에서 래핑할 객체를 받아서, 이 객체의 기능을 확장합니다. 기존 객체의 기능을 변경하지 않고 새로운 기능을 추가할 수 있습니다.
Java 코드를 통해 Decorator Pattern을 살펴보겠습니다. 예를 들어, 커피에 물, 우유, 설탕 등을 추가하는 경우를 생각해보겠습니다. 먼저, 커피를 나타내는 인터페이스를 만듭니다.
public interface Coffee {
public String getDescription();
public double getCost();
}
다음으로, 커피 객체를 구현합니다.
public class SimpleCoffee implements Coffee {
public String getDescription() {
return "Simple coffee";
}
public double getCost() {
return 1.0;
}
}
이제 Decorator 클래스를 만들어서 커피에 물, 우유, 설탕 등을 추가할 수 있습니다.
public abstract class CoffeeDecorator implements Coffee {
protected final Coffee decoratedCoffee;
public CoffeeDecorator(Coffee decoratedCoffee) {
this.decoratedCoffee = decoratedCoffee;
}
public String getDescription() {
return decoratedCoffee.getDescription();
}
public double getCost() {
return decoratedCoffee.getCost();
}
}
이제 물, 우유, 설탕을 추가하는 Decorator 클래스를 만들어봅시다.
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
public String getDescription() {
return super.getDescription() + ", Milk";
}
public double getCost() {
return super.getCost() + 0.5;
}
}
public class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
public String getDescription() {
return super.getDescription() + ", Sugar";
}
public double getCost() {
return super.getCost() + 0.2;
}
}
public class WaterDecorator extends CoffeeDecorator {
public WaterDecorator(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
public String getDescription() {
return super.getDescription() + ", Water";
}
public double getCost() {
return super.getCost() + 0.1;
}
}
이제 커피 객체에 물, 우유, 설탕을 추가할 수 있습니다.
Coffee simpleCoffee = new SimpleCoffee();
System.out.println(simpleCoffee.getDescription() + " $" + simpleCoffee.getCost());
Coffee milkCoffee = new MilkDecorator(simpleCoffee);
System.out.println(milkCoffee.getDescription() + " $" + milkCoffee.getCost());
Coffee sugarMilkCoffee = new SugarDecorator(milkCoffee);
System.out.println(sugarMilkCoffee.getDescription() + " $" + sugarMilkCoffee.getCost());
Coffee waterSugarMilkCoffee = new WaterDecorator(sugarMilkCoffee);
System.out.println(waterSugarMilkCoffee.getDescription() + " $" + waterSugarMilkCoffee.getCost());
결과는 다음과 같습니다.
Simple coffee $1.0
Simple coffee, Milk $1.5
Simple coffee, Milk, Sugar $1.7
Simple coffee, Milk, Sugar, Water $1.8
이처럼 Decorator Pattern을 사용하면, 기존 코드를 수정하지 않고 객체의 기능을 동적으로 확장할 수 있습니다.
Decorator Pattern은 객체의 기능을 확장할 때 유용한 디자인 패턴입니다. 이 패턴은 기존 코드를 수정하지 않고, 객체의 기능을 동적으로 확장할 수 있는 장점이 있습니다. 이를 위해 Decorator 클래스를 사용하며, 래핑된 객체의 기능을 확장합니다. Decorator Pattern은 개방-폐쇄 원칙을 준수하면서도, 유연한 기능 확장을 가능하게 합니다.
Reference : Decorator Pattern: 객체의 기능을 동적으로 확장하기 위한 디자인 패턴
'개발' 카테고리의 다른 글
Command Pattern: 명령을 객체화하여 실행 취소, 재실행 등의 기능을 제공하는 디자인 패턴 (0) | 2023.04.05 |
---|---|
Strategy Pattern: 알고리즘을 인터페이스로 분리하여 변경 가능하게 만드는 디자인 패턴 (0) | 2023.04.05 |
Proxy Pattern: 객체에 대한 접근을 제어하고 보안성을 강화하는 방법 (0) | 2023.04.05 |
Composite Pattern: 객체들의 계층적인 구조를 관리하기 위한 디자인 패턴 (0) | 2023.04.05 |
Prototype Pattern: 객체 생성을 효율화하기 위한 디자인 패턴 (0) | 2023.04.05 |