기존 코드를 변경하지 않고 부가적인 기능을 추가하는 패턴이다.
상속이 아닌 위임을 사용해서 보다 유연하게(런타임)에 부가 기능을 추가하는 것도 가능하다.
public interface CommentService {
void addComment(String 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 SpamFilterCommentDecorator(CommentService commentService) {
super(commentService);
}
@Override
public void addComent(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 DefaultCommentService implements CommentService {
@Override
public void addComment(String comment) {
System.our.println(comment);
}
}
public class Client {
private CommentService commentService;
public Client(CommentService commentService) {
commentService.addComment(comment);
}
}
public class App {
private static boolean enableSpamFilter = true;
private static boolean enabledTrimming = true;
public static void main(String[] args) {
CommentService commentService = new DefaultCommentService();
if(enableSpamFilter) {
commentService = new SpamFilterCommentDecorator(commentService);
}
if(enableTrimming) {
commentService = new TrimmingCommentDecorator(commentService);
}
Client client = new Client(commentService);
client.writeComment("오징어 게임");
client.writeComment("보는게 하는거보다 재미있을 수가 없지...");
}
}