ComputerScience/디자인 패턴
[디자인 패턴] 데코레이트 패턴
slown
2024. 6. 5. 21:40
목차?
1.데코레이트 패턴?
2.데코레이트 패턴 장단점
3.데코레이트 구현
1.데코레이트 패턴?
데코레이트 패턴은 객체의 기능을 동적으로 추가하거나 확장할 수 있는 구조적 디자인 패턴입니다. 이 패턴은 상속 대신 객체 조합을 활용하여 기능을 확장하는 방식으로, 더 유연하고 유지보수성이 높은 코드를 작성할 수 있게 합니다.
2.데코레이트 패턴 장단점
데코레이트 패턴의 장단점은 다음과 같습니다.
장점
- 유연한 기능 확장:
- 상속 대신 객체 조합을 통해 기능을 동적으로 추가하거나 제거할 수 있어, 매우 유연하게 기능을 확장할 수 있습니다.
- 런타임에 객체의 행동을 변경할 수 있어, 다양한 요구사항을 쉽게 반영할 수 있습니다.
- 단일 책임 원칙 준수:
- 각 클래스가 하나의 책임만 가지게 되므로, 클래스의 책임이 명확해지고 유지보수가 용이해집니다.
- 기능 추가나 변경이 필요한 경우, 해당 기능을 담당하는 데코레이터 클래스만 수정하면 되므로, 코드의 수정이 쉬워집니다.
- 재사용성 향상:
- 기능이 작은 단위로 분리되기 때문에, 각 데코레이터 클래스는 독립적으로 재사용될 수 있습니다.
- 여러 데코레이터를 조합하여 다양한 기능을 쉽게 구현할 수 있습니다.
- 투명성:
- 데코레이터 패턴은 클라이언트 코드에 투명하게 작동합니다. 클라이언트는 기본 객체와 데코레이터 객체를 구분하지 않고 사용할 수 있습니다.
단점
- 객체 수 증가:
- 기능을 추가할 때마다 새로운 데코레이터 객체를 생성해야 하므로, 객체 수가 늘어날 수 있습니다.
- 이는 메모리 사용량 증가와 객체 관리의 복잡성을 초래할 수 있습니다.
- 복잡성 증가:
- 데코레이터가 많아지면 클래스 계층 구조가 복잡해질 수 있습니다.
- 객체의 기능을 파악하기 위해 여러 데코레이터 클래스를 살펴봐야 하므로, 코드 이해도가 떨어질 수 있습니다.
- 디버깅 어려움:
- 여러 데코레이터가 조합되어 작동하므로, 디버깅 과정에서 실제 객체의 상태나 동작을 추적하기 어려울 수 있습니다.
- 중첩된 데코레이터들 사이에서 버그를 찾아내는 것이 어려울 수 있습니다.
- 호환성 문제:
- 기존 코드에 새로운 데코레이터를 추가하는 과정에서, 데코레이터가 올바르게 적용되지 않으면 예상치 못한 동작을 할 수 있습니다.
- 특히, 데코레이터가 여러 개 중첩되어 있을 때, 각 데코레이터가 올바르게 상호작용하는지 확인하는 것이 중요합니다.
3.데코레이트 구현
public interface Coffee {
String getDescription();
double getCost();
}
public class SimpleCoffee implements Coffee{
@Override
public String getDescription() {
// TODO Auto-generated method stub
return "Simple Coffee";
}
@Override
public double getCost() {
// TODO Auto-generated method stub
return 5.0;
}
}
public abstract class CoffeeDecorator implements Coffee{
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription();
}
@Override
public double getCost() {
return decoratedCoffee.getCost();
}
}
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription() + ", Milk";
}
@Override
public double getCost() {
return decoratedCoffee.getCost() + 1.5;
}
}
public class MochaDecorator extends CoffeeDecorator{
public MochaDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription() + ", Mocha";
}
@Override
public double getCost() {
return decoratedCoffee.getCost() + 2.0;
}
}
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
Coffee simpleCoffee = new SimpleCoffee();
System.out.println(simpleCoffee.getDescription() + " $" + simpleCoffee.getCost());
Coffee milkCoffee = new MilkDecorator(simpleCoffee);
System.out.println(milkCoffee.getDescription() + " $" + milkCoffee.getCost());
Coffee mochaCoffee = new MochaDecorator(milkCoffee);
System.out.println(mochaCoffee.getDescription() + " $" + mochaCoffee.getCost());
}
}