자바생
article thumbnail
Published 2022. 11. 6. 19:17
Decorator Pattern Design Pattern
728x90

데코레이터 패턴이란?

데코레이터 패턴은 프록시 패턴과 동일하게 ‘프록시’를 사용하는 방법이지만 둘은 그 의도(intent)가 다릅니다. 프록시는 주로 접근 제어를 목적으로, 데코레이터는 새로운 기능 추가가 목적으로 정의됩니다.

즉, 데코레이터 또한 서버와 프록시가 같은 인터페이스를 구현하여 클라이언트는 서버에게 직접적인 요청이 아닌 프록시를 통해 요청을 보냅니다. 그리고 클라이언트 입장에서는 서버에게 요청을 한 것인지, 프록시에게 요청을 한것인지 모르게 되어서 요구 사항 변경 시 클라이언트 코드는 변경되지 않습니다.

그러면 Decorator pattern이 어떻게 생겼는지 코드로 보겠습니다.

 

상황 예시

데코레이터 패턴은 새로운 기능 추가를 목적으로 사용한다고 했습니다. 그러면 데코레이터 패턴을 쉽게 이해하기 위해서 예시를 하나 들어보겠습니다.

사람은 밖으로 나가기 위해 옷을 입고, 신발을 신어야합니다.

이때 사람에 추가된 기능을 옷, 신발이라고 생각해보고 데코레이터 패턴을 사용하여 적용해보겠습니다.

 

데코레이터 패턴 코드

 

Component

public interface Component {
    void operation();
}

 

Complete

밖으로 나가게 되는 메인 비즈니스 로직이라고 가정하겠습니다.

public class Complete implements Component{
    @Override
    public void operation() {
        System.out.println("집을 나선다");
    }
}

 

Shoes

public class Shoes implements Component{

    private final Component component;

    public Shoes(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        System.out.println("신발을 신는다");
        component.operation();
    }
}

 

Clothes

public class Clothes implements Component{

    private final Component component;

    public Clothes(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        System.out.println("옷을 입는다");
        component.operation();
    }
}

 

Human

public class Human {

    private final Component component;

    public Human(Component component) {
        this.component = component;
    }

    void execute() {
        component.operation();
    }
}

 

Test

public class DecoratorTest {

    @Test
    void decoratorTest() {
        Component complete = new Complete();
        Component shoes = new Shoes(complete);
        Component clothes = new Clothes(shoes);
        Human human = new Human(clothes);

        human.execute();
    }
}

/*
옷을 입는다
신발을 신는다
집을 나선다
*/

complete는 집 밖을 나가는 행위로 메인 비즈니스 로직을 뜻합니다.

그래서 밖을 나가기 위해서는 옷과 신발을 신어야하기 때문에 Component를 구현하는 shose와 clothes 클래스를 생성했습니다.

human이 execute를 하면 옷을 입고(clothes) → 신발을 신고(shoes) → 집을 나섭니다(complete)

 

의존관계

 

클래스 의존관계

 

 

런타임 의존관계

 

 

확장

하지만 Shoes와 Clothes는 추가할 기능이고, 메인 비즈니스 로직은 Complete입니다. 그래서 Decorator와 Component를 구별하기 위해서 새로운 Decorator 클래스를 하나 생성하여 Shose와 Clothes를 상속하게 하면 됩니다.

 

데코레이터 코드

 

Decorator

public class Decorator implements Component {

    private final Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        component.operation();
    }
}

Component 인터페이스를 구현하는 추상 클래스인 Decorator 를 생성하고, Clothes와 Shoes는 Decorator 를 상속합니다.

 

Clothes

public class Clothes extends Decorator {

    public Clothes(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        System.out.println("옷을 입는다");
        super.operation();
    }
}

 

Shoes

public class Shoes extends Decorator {

    public Shoes(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        System.out.println("신발을 신는다");
        super.operation();
    }
}

Shoes와 Clothes 클래스는 Decorator 구체 클래스를 상속하기 때문에 Decorator의 생성자를 호출해야합니다. 그래서 Decorator 생성자를 호출하고 Shoes, Clothes에 대한 로직을 수행하고 다음 component를 실행합니다.

 

Test

public class DecoratorTest {

    @Test
    void decoratorTest() {
        Component complete = new Complete();
        Decorator shoes = new Shoes(complete);
        Decorator clothes = new Clothes(shoes);
        Human human = new Human(clothes);

        human.execute();
    }
}

/*
옷을 입는다
신발을 신는다
집을 나선다
*/

 

클래스 의존관계

 

정리

데코레이터 패턴은 프록시 패턴과 유사하게 ‘프록시’를 사용하는 패턴입니다. 다만 프록시와 다르게 데코레이터는 새로운 기능을 추가하기 위한 의도를 가지고 있습니다.

새로운 기능을 추가할 때 Decorator를 상속하는 클래스를 생성하여 구현하면 됩니다. 하지만 이어붙이는 데코레이터의 수가 많이 늘어날수록 가독성을 해치는 단점이 있습니다.

 

 

728x90

'Design Pattern' 카테고리의 다른 글

Template Callback Pattern  (0) 2022.11.01
Singleton Pattern  (0) 2022.03.17
Command Pattern  (0) 2022.03.15
State Pattern  (0) 2022.03.12
Strategy Pattern  (0) 2022.03.04
profile

자바생

@자바생

틀린 부분이 있다면 댓글 부탁드립니다~😀

검색 태그