본문 바로가기

카테고리 없음

데코레이션 (Decoration) 패턴

SMALL

https://velog.io/@sillutt/%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%EC%85%98-Decoration-%ED%8C%A8%ED%84%B4

 

데코레이션 (Decoration) 패턴

기존의 코드를 변경하지 않으면서 부가적인 기능(Dynamic) 을 추가할 수 있음runtime의 기존 코드를 확장하는 방법.상속이 아닌 위임을 사용해서 보다 유연하게 런타임에 부가 기능을 추가하는 것도

velog.io

Decoration Pattern

기존의 코드를 변경하지 않으면서 부가적인 기능(Dynamic) 을 추가할 수 있음
runtime의 기존 코드를 확장하는 방법.
상속이 아닌 위임을 사용해서 보다 유연하게 런타임에 부가 기능을 추가하는 것도 가능하다. 컴포짓과 다르게 단 한개의 데코레이터가 감싸는 컴포넌트 타입의 인스턴스를 가진다.


Example Code

public class Client {
	private CommentService commentService;

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

	public static void main(String[] args) {
		Client client = new Client(new TrimingCommentService());
		client.writeComment("game");
		client.writeComment("fun...");
	}
}

기존 코드를 변경하지 않고 새로운 기능을 더해서 상속 관계의 기능을 정의한다.

public class TrimingCommentService extends CommentService {
	@Override
	public void addComment(String comment) {
		super.addComment(trimComment);
	}
	private String trim(String comment) {
		return comment.replace("...", "");
	}
}

만약 다른 필터링 서비스를 추가하고 싶다면 대부분의 언어들은 다중 상속을 지원하지 않기 때문에 새로운 클래스를 작성해야 한다. 클라이언트의 코드는 변경되지 않는다. decorator pattern 을 사용하지 않으면 각각의 클래스를 상속하여 사용한다는 단점이 있다.


Example Code - 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);
	}
	
}
public class TrimingCommentDecorator extends CommentDecorator {
	public TrimmingCommentDecorator(CommentService commentService) {
		super(CommentService);
	}

	public CommentDecorator(CommentService commentService) {
		thiscommentService = commentService;
	}

	@Override
	public void addComment(String comment){
		commentService.addComment(comment);
	}
}
public class SpamFilteringCommentDecorator extends CommentDecorator {
	public TrimmingCommentDecorator(CommentService commentService) {
		super(CommentService);
	}

	public CommentDecorator(CommentService commentService) {
		thiscommentService = commentService;
	}

	@Override
	public void addComment(String comment){
		if(isNotSpam(comment)) {
		commentService.addComment(comment);
		}
	}
}

Client 코드에서는 CommentService 만 이용하면 된다.

public class Client {
	private CommentService commentService;

	public Client (CommentService commentService) {
		this.commentService = commentService;
	}
	public writeComment(String comment) {
		commentService.addComment(comment);
	}
}

장단점

장점

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

단점

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

Example

InputStream

Adapter 패턴과 유사하다. Adapter 패턴에서는 한 인터페이스를 다른 인터페이스로 변환하지만, 과정 중에서 다른 타입이 감싸고 있다. 감싸는 인터페이스에 포함된 기능들이 확장되고 있기 때문에 Decorator 패턴이라고도 볼 수 있다.

Collection - checked *

Collection의 기능 중 checked 로 시작하는 몇몇 메소드들이 있다. 이 메소드들은 인스턴스 안에 들어가는 객체의 타입을 검증한다.

Collection - Synchronized

Collection에 접근하는 내용들이 직렬화되어 처리할 수 있도록 변환하는 메소드

Collections - unmodiefiable

해당 Collection을 불변한 객체로 만드는 메소드

 
SMALL