디자인 패턴 정리 - Decorator Pattern

2021. 11. 19. 16:16·CS/GoF의 Design Pattern 정리

Decorator Pattern

  • 객체에 추가적인 요건을 동적으로 추가해주는 패턴으로, 서브 클래스를 만들지 않고 기능을 유연하게 확장할 수 있게 한다.
  • 데코레이터 패턴에서의 상속은 공통적인 타입으로 추상화하기 위한 용도가 주 목적이다.
  • 데코레이터는 인터페이스/추상 클래스로서 역활을 하고 이를 상속받은 클래스들은 컴포넌트를 꾸미기 위한 구현을 갖게 된다.
  • 컴포넌트는 바로 사용되거나 데코레이터레가 붙어서 사용될 수 있다.

예시

  • 데코레이터 패턴을 일상생활의 예시로 커피를 들 수 있다.
  • 커피를 생각해보면 에스프레소, 콜드블루는 컴포넌트가 될 수 있고 얼음, 시나몬 가루, 우유, 두유, 샷, 자바칩 등은 모두 데코레이터 클래스를 상속받은 데코를 위한 클래스가 될 수 있다.
  • 이때, 최상위 추상 클래스/인터페이스를 Beverage로 두고 에스프레소, 콜드블루 컴포넌트는 Beverage를 상속받는다.
  • 데코들의 추상화를 위해 Beverage를 상속받은 BeverageDecorator를 선언하고, 모든 데코 용 클래스들은 BeverageDecorator를 상속받는다.
  • 형태 → 자바칩 ( 우유 ( 얼음 ( 얼음 ( 샷 ( 에스프레소 ) ) ) ) ), 이때 순서는 상관이 없다.

다이어그램

  • Display 추상 클래스를 최상위 클래스로 두고 기본 컴포넌트로 HudDisplay를 갖는다.
  • HudDisplay를 꾸밀 수 있는 Deco용 클래스들의 추상화 용도로 Display를 상속한 추상 클래스 DisplayDecorator를 둔다.
  • Message, Time, Weater, Speed 클래스들은 DisplayDecorator를 상속받아서 구현한다.
  • 결국 데코 클래스들은 Display 클래스의 하위 클래스로서 데코 클래스에서 반환한 클래스에 대해 데코를 반복할 수 있게 된다.

Main.java _ 코드

public class MainWindow extends FrameWindow {
    private static final String MAIN_TITLE = "woonsik's Window";
    private static final int X = 250;
    private static final int Y = 100;
    private static final int WIDTH = 600;
    private static final int HEIGHT = 100;

    private ArrayList<String> displayList;
    private JFrame frame;

    public MainWindow(String title, ArrayList<String> list) {
        displayList = list;
        frame = createWindow(title, X, Y, WIDTH, HEIGHT * (displayList.size() + 1));
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                closeWindow();
                System.exit(0);
            }
        });
    }

    public JFrame createWindow(String title, int x, int y, int width, int totalHeight) {
        JFrame frame;
        frame = new JFrame(title);
        frame.setBounds(x, y, width, totalHeight);

        JPanel panel = createPanel(width, totalHeight);
        frame.getContentPane().add(panel);
        frame.pack();
        frame.setVisible(true);
        return frame;
    }

    public void closeWindow() {
        frame.setVisible(false);
        frame.dispose();
    }

    public JPanel createPanel(int width, int totalHeight) {
        // 제일 바탕에 놓일 패널 생성
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        panel.setMinimumSize(new Dimension(width, totalHeight));
        panel.setPreferredSize(new Dimension(width, totalHeight));

        Display display = new HudDisplay(WIDTH, HEIGHT);

        // 새로운 장식이 추가될 때마다 새로운 패널이 생성되고, 그 안에 기존 패널이 추가된다.
        for (String name : displayList) {
            if (name.equals("speed")) {
                display = new SpeedometerDisplay(display, WIDTH, HEIGHT);
            } else if (name.equals("time")) {
                display = new TimeDisplay(display, WIDTH, HEIGHT);
            } else if (name.equals("weather")) {
                display = new WeatherDisplay(display, WIDTH, HEIGHT);
            } else if (name.equals("message")) {
                display = new MessageDisplay(display, WIDTH, HEIGHT);
            }
        }
        // 장식이 모두 끝나면 최종 디스플레이 패널을 생성함.
        panel.add(display.create());

        // 높이를 출력
        System.out.println("disply.totalHeight = " + display.getHeight());

        // 디스플레이마다 각각의 내용을 화면에 보임
        display.show();
        return panel;
    }

    public static void main(String[] args) {
        final String displayFileName = "displays.txt";
        ArrayList<String> list;

        LoadHudDisplays loadDisplay = new LoadHudDisplays(displayFileName);
        list = loadDisplay.load();

        System.out.printf("display.size() = %d\n", list.size());
        for (String s : list) {
            System.out.println(s);
        }

        new MainWindow(MainWindow.MAIN_TITLE, list);
    }
}

 

설명

main() → MainWindow() → createWindow() → createPanel()

  • createPanel 에서 기본 컴포넌트로서 HudDisplay를 만든다. 코드
  • 이후 display.txt파일에 작성된 순서대로 디스플레이에 기능 목록을 추가한다.
  • 데코 용 클래스 : MessageDisplay, SpeedmeterDisplay, TimeDisplay, WeatherDisplay

로직

Display 클래스를 상속한 DisplayDecorator 클래스는 데코들의 추상 클래스. 이 추상 클래스를 여러 데코 용 클래스들이 상속받아서 데코를 하게 된다.

display.txt파일을 읽고 해당 순서대로 Deco클래스들을 감싸게 되고 마지막에 감싼 구현 클래스의 display.create()를 호출하게 된다.

해당 구현 클래스의 create 메소드를 들어가면 전달 받은 클래스의 create()를 전달받아서 처리한다. 따라서 최초의 컴포넌트 create()까지 들어가고 반환되면서 최종 create()까지 호출이 된다.

결과

1) displays.txt

time
weather
speed
speed
time
message

형태 → message ( time ( speed ( speed ( weather ( time ( HudDisplay ) ) ) ) ) )

2) displays.txt

message
speed
time
weather
time

형태 → time ( weather ( time ( speed ( message ( HudDisplay ) ) ) ) )

반응형
저작자표시 비영리 변경금지 (새창열림)

'CS > GoF의 Design Pattern 정리' 카테고리의 다른 글

디자인 패턴 정리 - Singleton Pattern  (1) 2021.11.19
디자인 패턴 정리 - Factory Method Pattern  (0) 2021.11.19
디자인 패턴 정리 - Observer Pattern  (2) 2021.11.19
디자인 패턴 정리 - Strategy Pattern  (0) 2021.11.19
디자인 패턴 정리 - Polymorphism  (0) 2021.11.19
'CS/GoF의 Design Pattern 정리' 카테고리의 다른 글
  • 디자인 패턴 정리 - Singleton Pattern
  • 디자인 패턴 정리 - Factory Method Pattern
  • 디자인 패턴 정리 - Observer Pattern
  • 디자인 패턴 정리 - Strategy Pattern
구름뭉치
구름뭉치
구름의 개발일기장
  • 구름뭉치
    구름 개발일기장
    구름뭉치
  • 전체
    오늘
    어제
    • ALL (283)
      • 프로젝트 (23)
        • 토스페이먼츠 PG 연동 시리즈 (12)
        • JWT 방식 인증&인가 시리즈 (6)
        • 스우미 웹 애플리케이션 프로젝트 (1)
        • 스프링부트 기본 보일러 플레이트 구축 시리즈 (2)
        • 마이크로서비스 아키텍쳐 시리즈 (1)
      • 스프링 (43)
        • 스프링부트 API 설계 정리 (8)
        • 스프링부트 RestAPI 프로젝트 (18)
        • 스프링부트 WebSocket 적용기 (3)
        • 스프링 JPA 정리 시리즈 (5)
        • 스프링 MVC (5)
        • 스프링 배치 (2)
        • 토비의 스프링 정리 (2)
      • 기술 학습 (28)
        • 아파치 카프카 (9)
        • 클린 코드 (4)
        • 디자인 패턴의 아름다움 (2)
        • 모던 자바 인 액션 (7)
        • JVM 스레드 딥다이브 (6)
      • Web (25)
        • 정리글 (20)
        • GraphQL 정리글 (2)
        • Jenkins 정리글 (3)
      • 취업 (6)
      • CS (77)
        • 네트워크 전공 수업 정리 (11)
        • OSI 7계층 정리 (12)
        • 운영체제 정리 (19)
        • 데이터베이스 정리 (5)
        • MySql 정리 (17)
        • GoF의 Design Pattern 정리 (12)
      • 알고리즘 (70)
        • 백준 (56)
        • 프로그래머스 (12)
        • 알고리즘 정리본 (1)
      • 기초 지식 정리 (2)
      • 일상 (8)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    레이저
    크로아티아
    동유럽
    마우스 패드
    마우스
    류블라냐
    부다페스트
    키보드 손목 받침대
    mx master s3 for mac
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
구름뭉치
디자인 패턴 정리 - Decorator Pattern
상단으로

티스토리툴바