데코레이터 패턴 Decorator Pattern

데코레이터 패턴

  • 기존 코드를 변경하지 않고 부가 기능을 추가하는 패턴
  • 프록시 패턴과 거의 유사한 디자인 패턴이다.
    • 기존 코드와 같은 데이터 타입을 가진다.
    • 새로운 클래스를 만들지 않고 기존 기능을 조합할 수 있다.
    • 런타임 때 원하는 데코레이터를 결정할 수 있다.

java.io와 데코레이터 패턴

  • java.io의 스트림을 다루는 클래스는 데코레이터 패턴의 전형적인 형태를 띈다.
  • InputStream은 바이트를 스트림 형태로 제공한다.
  • BufferedInputStream은 InputStream의 데코레이터이다.
    • 바이트 스트림을 버퍼를 활용하여 성능을 높힌다.
    • InputStream을 상속하기 때문에 InputStream 대신 사용할 수 있다.
  • InputStream의 데코레이터로 LowerCaseInputStream을 아래와 같이 구현하였다. 영문자를 소문자로 바꾼다.
public class LowerCaseInputStream extends InputStream {
    private final InputStream in;

    public LowerCaseInputStream(InputStream in) {
        this.in = in;
    }

    @Override
    public int read() throws IOException {
        int c = in.read();
        return (c == -1 ? c : Character.toLowerCase((char)c));
    }
}
  • 아래 코드를 보면 InputStream을 BufferedInputStream가 감싸고 LowerCaseInputStream가 한 번 더 감싼다.
try(InputStream resourceAsStream = InputTest.class.getClassLoader().getResourceAsStream("file/test.txt");
    InputStream in = new LowerCaseInputStream(new BufferedInputStream(resourceAsStream));){
    int c;
    while((c = in.read()) >= 0) {
        System.out.print((char)c);
    }
}
  • file/text.txt 의 내용이 ‘Hello World’라면, ‘hello world’로 프린트한다.

참조

  • 백기선, 디자인 패턴 강의(https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4)
  • O’Reilly, “헤드 퍼스트 디자인 패턴”