본문 바로가기
Develop/Fundmental

Decorator pattern (데코레이터 패턴)

by 3-stack 2022. 5. 3.

데코레이터 패턴(Decorator pattern)

주어진 상황 및 용도에 따라 어떤 객체에 책임을 덧붙이는 패턴으로, 기능 확장이 필요할 때 서브클래싱 대신 쓸 수 있는 유연한 대안이 될 수 있다.

기존 코드를 수정하지 않고도 데코레이터 패턴을 통해 행동을 확장시킬 수 있다.

구성과 위임을 통해 실행중에 새로운 행동을 추가할 수 있다.

 

Component

실질적인 인스턴스를 컨트롤하는 역할. ConcreteComponent와 Decorator가 구현할 인터페이스.

ConcreteComponent

Component의 실질적인 인스턴스의 부분으로 책임의 주체. Decorator를 받을 객체.

Decorator

Decorator를 할 객체의 추상클래스/인터페이스. 즉, 기능 추가를 할 객체는 이 객체를 상속/구현한다.

Concrete Decorator

실질적인 장식 인스턴스 및 정의이며 추가된 책임의 주체

 

 

# 코드를 통해 알아보자.

- 코멘트의 스팸을 필터링하거나 trim해주는 코멘트 필터 기능을 사용하는 모습이다.

public class App {
  private static boolean enableSpamFilter = true;
  private static boolean enableTrimFilter = true;

  public static void main(String[] args) {
    CommentFilter commentFilter = new CommentFilter();
    if (enableSpamFilter) {
      commentFilter = new CommentSpamFilter();
    }
    if (enableTrimFilter) {
      commentFilter = new CommentTrimFilter();
    }

    commentFilter.handleComment("타짜");
    commentFilter.handleComment("묻고 더블로 가!...");
    commentFilter.handleComment("http://abcdef.com");
  }
}

- 기본 코멘트필터

public class CommentFilter {
  public void handleComment(String comment) {
    System.out.println(comment);
  }
}

- "..."을 정리하는 TrimFilter

public class CommentTrimFilter extends CommentFilter {
  @Override
  public void handleComment(String comment) {
    super.handleComment(trim(comment));
  }

  private String trim(String comment) {
    return comment.replace("...", "");
  }
}

- URL을 걸러주는 SpamFilter

public class CommentSpamFilter extends CommentFilter {
  @Override
  public void handleComment(String comment) {
    if (!isSpam(comment)) {
      super.handleComment(comment);
    }
  }

  private boolean isSpam(String comment) {
    return comment.contains("http");
  }
}

 

각 필터의 행동별로 클래스를 만들었다,

이런 사용은 아래와 같은 경우 단점이 있다.

- 스팸도 필터하고 트림도 해야하는 경우, 새로운 클래스를 만들어야한다.

- 런타임 상황에서 객체에 행동을 추가할 수 없다. 정적으로 행동패턴별 클래스를 만들기 때문에

 

 

# 데코레이터 패턴을 적용해보자

1. ConcreteComponent와 Decorator가 구현할 인터페이스

public interface CommentFilterable {
  public void handleComment(String comment);
}

2. ConcreteComponent = CommentFilter 클래스

public class CommentFilter implements CommentFilterable {
  public void handleComment(String comment) {
    System.out.println(comment);
  }
}

3. Decorator = CommentFilterDecorator 클래스

- CommentFilterable을 생성자로 받아서 handleComment 한다.

public class CommetFilterDecorator implements CommentFilterable {
  private CommentFilterable commentFilterable;

  public CommetFilterDecorator(CommentFilterable commentFilterable) {
    this.commentFilterable = commentFilterable;
  }

  @Override
  public void handleComment(String comment) {
    commentFilterable.handleComment(comment);
  }
}

4. CommentTrimFilterDecorator

- super.handleComment = commentFilterable.handleComment

- 생성자로 전달받은 CommentFilteralbe의 handleComment에 행동이 추가되는 것을 볼 수 있다.

public class CommentTrimFilterDecorator extends CommetFilterDecorator {
  public CommentTrimFilterDecorator(CommentFilterable commentFilterable) {
    super(commentFilterable);
  }

  @Override
  public void handleComment(String comment) {
    super.handleComment(trim(comment));
  }

  private String trim(String comment) {
    return comment.replace("...", "");
  }
}

5. CommentSpamFilterDecorator

public class CommentSpamFilterDecorator extends CommetFilterDecorator {
  public CommentSpamFilterDecorator(CommentFilterable commentFilterable) {
    super(commentFilterable);
  }

  @Override
  public void handleComment(String comment) {
    if (!isSpam(comment)) {
      super.handleComment(comment);
    }
  }

  private boolean isSpam(String comment) {
    return comment.contains("http");
  }
}

 

'Develop > Fundmental' 카테고리의 다른 글

테스트 어떻게 해야 할까...???  (0) 2023.02.28
메모리 매핑 (Memory-mapped file)  (0) 2022.11.20
Bridge Pattern(브릿지 패턴)  (0) 2022.05.01
Adapter Pattern (어댑터 패턴)  (0) 2022.05.01
Builder Pattern (빌더 패턴)  (0) 2022.04.28

댓글