목차
어떤 상황에서 쓰일까?
댓글 작성 서비스는 필터를 받아서 동작한다.
이때 공백을 자르는 필터가 있을 것이고, 어떤 문자열을 자르는 필터가 있을 것이다.
문자열을 자르는 필터는 new Client(new SpamFilter()); 로 사용하고
공백을 자르는 필터는 new Client(new TrimFilter()); 로 사용할 것이다.
그렇다면 문자열과 공백 둘다 자르는 필터는 어떻게 만들 수 있을까??
SpamAndTrimFilter?
여기서 필터의 기능이 더 추가된다면..?
SpamAndTrimAnd...And....Filter..?
각 필터들의 기능은 그대로 놔두면서, 런타임 시에 이 필터들이 조합되며 동작하게 할 수는 없을까??
데코레이터 패턴이란?
런타임에서 기존 코드를 변경하지 않으면서 부가적인 기능을 추가할 수 있는 패턴이다.
런타임에서 유연하게 객체를 조립하여 사용할 수 있다!
장점
- 새로운 클래스를 만들지 않고 기존 기능을 조합할 수 있다
- 컴파일 시점이 아닌 런타임에 동적으로 기능을 변경할 수 있다
단점
- 데코레이터 조립 코드가 복잡하다
구현코드
기존코드
public class CommentService {
public void addComment(String comment) {
System.out.println(comment);
}
}
-------------------------------------------------------------------
public class TrimmingCommentService extends CommentService {
@Override
public void addComment(String comment) {
super.addComment(trim(comment));
}
private String trim(String comment) {
return comment.replace("...", "");
}
}
-------------------------------------------------------------------
public class SpamFilteringCommentService extends CommentService {
@Override
public void addComment(String comment) {
boolean isSpam = isSpam(comment);
if (!isSpam) {
super.addComment(comment);
}
}
private boolean isSpam(String comment) {
return comment.contains("http");
}
}
public class Client {
private CommentService commentService;
public Client(CommentService commentService) {
this.commentService = commentService;
}
private void writeComment(String comment) {
commentService.addComment(comment);
}
public static void main(String[] args) {
Client client = new Client(new SpamFilteringCommentService()); //⭐
client.writeComment("오징어게임");
client.writeComment("보는게 하는거 보다 재밌을 수가 없지...");
client.writeComment("http://whiteship.me");
}
}
⭐ 부분이 계속 변하게된다.
스팸문자열을 거르고 싶다면 SpamFilter... 공백을 제거하고싶다면 TrimFilter가 동작되게 하고싶다!
변경코드
public interface CommentService {
void addComment(String comment);
}
public class DefaultCommentService implements CommentService {
@Override
public void addComment(String comment) {
System.out.println(comment);
}
}
public class CommentDecorator implements CommentService {
private CommentService commentService;
public CommentDecorator(CommentService commentService) {
this.commentService = commentService;
}
@Override
public void addComment(String comment) {
commentService.addComment(comment);
}
}
public class SpamFilteringCommentDecorator extends CommentDecorator {
public SpamFilteringCommentDecorator(CommentService commentService) {
super(commentService);
}
@Override
public void addComment(String comment) {
if (isNotSpam(comment)) {
super.addComment(comment);
}
}
private boolean isNotSpam(String comment) {
return !comment.contains("http");
}
}
------------------------------------------------------------------------
public class TrimmingCommentDecorator extends CommentDecorator {
public TrimmingCommentDecorator(CommentService commentService) {
super(commentService);
}
@Override
public void addComment(String comment) {
super.addComment(trim(comment));
}
private String trim(String comment) {
return comment.replace("...", "");
}
}
public class App {
private static boolean enabledSpamFilter = true;
private static boolean enabledTrimming = true;
public static void main(String[] args) {
CommentService commentService = new DefaultCommentService();
if (enabledSpamFilter) {
commentService = new SpamFilteringCommentDecorator(commentService);
}
if (enabledTrimming) {
commentService = new TrimmingCommentDecorator(commentService);
}
Client client = new Client(commentService);
client.writeComment("오징어게임");
client.writeComment("보는게 하는거 보다 재밌을 수가 없지...");
client.writeComment("http://whiteship.me");
}
}
DefaultCommentService -> CommentService
CommentDecorator -> CommentService
SpamFilter -> CommentDecorator
TrimFilter -> CommentDecorator
디폴트가 아닌 변경될 수 있는 서비스들이 들어오는 CommentDecorator를 생성하고
CommentDecorator를 구현하는 필터들을 생성해서 런타임 시에 동적으로 적용될 수 있도록 하였다!
'Computer Science' 카테고리의 다른 글
Flyweight Pattern | 플라이웨이트 패턴 (0) | 2022.08.16 |
---|---|
Facade Pattern | 퍼사드 패턴 (0) | 2022.08.16 |
Composite Pattern | 컴포짓 패턴 (0) | 2022.08.15 |
Bridge Pattern | 브릿지 패턴 (0) | 2022.08.15 |
Adapter Pattern | 어댑터패턴 (0) | 2022.08.14 |