티스토리 뷰
728x90
1. 의미
- 기존 코드를 변경하지 않고 부가 기능을 추가하는 패턴
- 상속이 아닌 위임을 사용해서 보다 유연하게(런타임) 부가 기능을 추가하는 것도 가능하다.
2. 작성 방법
2.1. 기존 코드에 부가기능 추가 시, 상속의 한계
- CommentService : 댓글 서비스
- TrimmingCommentService : CommentService상속, Trim 부가기능 추가
- SpamFilteringCommentService : CommentService상속, SpamFilter 부가기능 추가
- Trim기능과, SpamFilter 기능을 모두 사용하고 싶다면 새로운 서비스를 추가해야하는 상황이 발생 -> 유연하지 않는 코드
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()); //기능추가에 따른 생성자 호출 변경 (TrimmingCommentService,SpamFilteringCommentService)
client.writeComment("오징어게임");
client.writeComment("보는게 하는거 보다 재밌을 수가 없지...");
client.writeComment("http://whiteship.me");
}
}
2.2. 데코레이턴 패턴으로 부가기능을 추가
- CommentService : 인터페이스 정의
- DefaultCommentService : ConcreateComponent정의 , CommentService에서 하던일
- CommentDecorator : ConcreateComponent를 호출하는 메인 Decorator
- TrimmingCommentDecorator : 메인 Decorator를 상속받은 부가 Decorator
- SpamFilteringCommentDecorator : 메인 Decorator를 상속받은 부가 Decorator
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 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 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 Client {
private CommentService commentService;
private static boolean enabledSpamFilter = true;
private static boolean enabledTrimming = true;
public Client(CommentService commentService) {
this.commentService = commentService;
}
public void writeComment(String comment) {
commentService.addComment(comment);
}
public static void main(String[] args) {
//9Line ~ 17Line 코드가 늘어나는건 어쩔 수 없음
//객체를 조합해서 동적으로 전달해주는것으로 생각해주자!
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");
}
}
3. 장점과 단점
- 장점
- 새로운 클래스를 만들지 않고 기존 기능을 조합할 수 있다.
- 단일 책임의 원칙 : 각자 해야할 일만 하면 된다.
- 컴파일 타임이 아닌 런타임에 동적으로 기능을 변경할 수 있다.
- 개방 폐쇄의 원칙 : 확장에는 개방되어있고, 수정에 있어서는 닫혀있는 구조가 되어야한다는 원칙
- 의존 관계 역전의 원칙 : 상위 모듈은 하위 모듈의 구현에 의존하면 안되며, 하위 모듈이 상위 모듈에서 정의한 추상 타입에 의존해야하는 원칙
- 대부분의 객체지향 원칙이 적용되어있어 굉장히 좋은 패턴
- 새로운 클래스를 만들지 않고 기존 기능을 조합할 수 있다.
- 단점
- 데코레이터를 조합하는 코드가 복잡할 수 있다.
728x90
'디자인 패턴' 카테고리의 다른 글
11. 플라이 웨이트 패턴 (0) | 2022.02.10 |
---|---|
10. 퍼사드 패턴 (0) | 2022.02.10 |
08. 컴포짓 패턴 (0) | 2022.02.10 |
07. 브릿지 패턴 (0) | 2022.02.10 |
06. 어댑터 패턴 (0) | 2022.02.10 |
댓글