구조 패턴: 데코레이터 패턴

xellos·2022년 4월 3일
0

디자인 패턴

목록 보기
8/20

소개

기존 코드를 변경하지 않고 부가적인 기능을 추가하는 패턴이다.
상속이 아닌 위임을 사용해서 보다 유연하게(런타임)에 부가 기능을 추가하는 것도 가능하다.

1) 장점

  1. 새로운 클래스를 만들지 않고 기존 기능을 조합할 수 있다.
  2. 컴파일 타임이 아닌 런타임에 동적으로 기능을 변경할 수 있다.

2) 단점

  1. 데코레이터를 조합하는 코드가 복잡해질 수 있다.

구현

1) 인터페이스

public interface CommentService {
	void addComment(String comment);
}

2) 인터페이스를 구현한 데코레이터 작성

이때, 위의 인터페이스를 구현한 구체 인터페이스를 가지고 있어야 한다.

public class CommentDecorator implements CommentService {

	private CommentService commentService;
    
    public CommentDecorator(CommentService commentService) {
    	this.commentService = commentService;
    }
    
    @Override
    public void addComment(String comment) {
    	commentService.addComment(comment);
    }
}

3) 데코레이터를 상속받는 기능 틀래스 작성

SpamFilteringCommentDecorator 클래스

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");
    }
}

TrimmingCommentDecorator 클래스

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("...", "");
    }
}

사용

1) 추가적인 기능이 없는 기본적인(Main) 서비스 구현

public class DefaultCommentService implements CommentService {

	@Override
    public void addComment(String comment) {
    	System.our.println(comment);
    }
}

2) CommentService 인터페이스를 사용하는 클라이언트 구현

public class Client {

	private CommentService commentService;
    
    public Client(CommentService commentService) {
    	commentService.addComment(comment);
    }
}

3) 실제 사용

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("보는게 하는거보다 재미있을 수가 없지...");
    }
}

0개의 댓글