Decorator Pattern: 객체의 기능을 동적으로 확장하기 위한 디자인 패턴

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.0Simple coffee, Milk $1.5Simple coffee, Milk, Sugar $1.7Simple coffee, Milk, Sugar, Water $1.8

이처럼 Decorator Pattern을 사용하면, 기존 코드를 수정하지 않고 객체의 기능을 동적으로 확장할 수 있습니다.

Decorator Pattern은 객체의 기능을 확장할 때 유용한 디자인 패턴입니다. 이 패턴은 기존 코드를 수정하지 않고, 객체의 기능을 동적으로 확장할 수 있는 장점이 있습니다. 이를 위해 Decorator 클래스를 사용하며, 래핑된 객체의 기능을 확장합니다. Decorator Pattern은 개방-폐쇄 원칙을 준수하면서도, 유연한 기능 확장을 가능하게 합니다.

Comments

Popular posts from this blog

Spring Cloud와 Apache Cassandra 사용하기

Spring Cloud Function으로 Serverless 개발하기

Portfolio Diversification Tips

개발 – 이슈링크 블로그

Cultures Log

Moments Log