데코레이터 패턴(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 |
댓글