런타임노트

[헤드퍼스트 디자인패턴] 7일차. 102-113pg 본문

책책책 책을 읽읍시다‼ ver.개발/[ 헤드퍼스트 디자인패턴 ]

[헤드퍼스트 디자인패턴] 7일차. 102-113pg

D269 2023. 5. 2. 20:27
728x90

7일차

헤드퍼스트 디자인패턴 [월요일]

102-113pg

요약

CHAPTER 02. 객체들에게 연락돌리기 (feat. 옵저버 패턴)

[라이브러리 속 옵저버 패턴 : 스윙라이브러리]

swing toolkit의 기본 구성 요소 중 JButton 클래스 : AbstractButton을 찾아보면 리스너를 추가/제거하는 메소드가 많음.

[할까말까 애플리케이션]

package com.book.doOrNot;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class SwingObserverExample {
    JFrame frame;

    public static void main(String[] args) {
        // 프레임을 만들고 그 안에 버튼을 추가하는 간단한 스윙 애플리케이션
        SwingObserverExample example = new SwingObserverExample();
        example.go();
    }

    public void go() {
        frame = new JFrame();

       JButton button = new JButton("할까? 말까?");
       // 버튼을 누르면 반응하면 천사와 악마 리스너(옵저버) 만들기
//       button.addActionListener(new AngelListener());
//       button.addActionListener(new DevilListener());

        // 람다 표현식으로 만들기
        button.addActionListener(event -> System.out.println("하지마! 아마 후회할걸?"));
        button.addActionListener(event -> System.out.println("그냥 저질러버려!"));
       
       // 프레임 속성 설정

    }

    // 옵저버의 클래스 정의 -> 람다식으로 구현하면 필요없음
//    class AngelListener implements ActionListener {
//        @Override
//        public void actionPerformed(ActionEvent e) {
//            System.out.println("하지마! 아마 후회할 걸?");
//        }
//    }
//
//    class DevilListener implements ActionListener {
//        // 주제(이 코드에서는 버튼)의 상태가 바뀌었을 때 update() 메소드가 아니라 actionPerformed 메소드가 호출됨.
//        @Override
//        public void actionPerformed(ActionEvent e) {
//            System.out.println("그냥 저질러 버렷!!!!");
//        }
//    }

}

[옵저버가 필요한 데이터를 골라서 가져가도록 해보기 - 풀 방식으로 코드 바꾸기]

주제 → 옵저버로 데이터를 보내는 푸쉬(push)

옵저버 ← 주제로부터 데이터를 당겨우는 풀(pull)

[새로 채운 디자인 도구상자]

  • 객체지향 원칙
    • 상호작용하는 객체 사이에서는 가능하면 느슨한 결합을 사용해야 한다.
  • 객체지향 패턴
    • 옵저버 패턴 : 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체에게 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다 의존성을 정의한다.

 

CHAPTER 03. 객체 꾸미기 (feat. 데코레이터 패턴)

상속을 남용하는 사례 → 객체 작성 : 실행 중에 클래스를 데코레이션하는 방법 배우기

 

 

 

발췌

💡 Observer 인터페이스를 구현하기만 하면 어떤 구상 클래스의 옵저버라도 패턴에 참여할 수 있습니다.
💡 옵저버 패턴을 사용하면, 주제가 데이터를 보내거나(푸시), 옵저버가 데이터를 가져올(풀) 수 있다. 일반적으로는 풀 방식이 더 ‘옳은’ 방식이라고 간주한다.

 

메모

책의 구성이 반복학습과 앞서 배웠던 내용을 짚고 넘어가 줘서 다시 앞 부분을 생각해볼 수 있어서 좋다.

 

 

 

숙제

106p 코드 순서 맞추기

package com.book.weatherStation.display;

import com.book.weatherStation.inteface.DisplayElement;
import com.book.weatherStation.inteface.Observer;
import com.book.weatherStation.subject.WeatherData;

public abstract class ForecaseDisplay implements Observer, DisplayElement {

    private WeatherData weatherData;
    private float currentPressure = 29.92f;
    private float lastPressure;
    public ForecaseDisplay(WeatherData weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
//        display(); 틀림
    }

    public void display() {
        // 디스플레이 코드
    }

    public void update() {
        lastPressure = currentPressure;
        currentPressure = weatherData.getPressure();
        display();
    }
}

 

 

 

109p 디자인원칙 경시대회 : 주어진 디자인 원칙으로 보고, 각 원칙이 옵저버 패턴에서 어떤식으로 쓰이는지 설명하기

 

 

원칙1. 애플리케이션에서 달라지는 부분을 찾아내고 달라지지 않는 부분과 분리한다.

이 원칙은 옵저버 패턴에서 계속 바뀌는 값을 받을 옵저버는 계속해서 달라지는 값을 받아낸다는 공통점이 있으므로 이것을 Observer 인터페이스로 분리

정답)

옵저버 패턴에서 변하는 것은 주제의상태와 옵저버의 개수, 형식입니다.

옵저버 패턴에서는 주제를 바꾸지 않고도 주제의 상태에 대해 의존하는 객체들을 바꿀 수있습니다. 나중에 바뀔 것을 대비해 두면 편하게 작업할 수 있습니다.

 

원칙2. 구현보다는 인터페이스에 맞춰서 프로그래밍한다.

Observer, Subject, Display interface를 만들고 그것에 맞춰서 프로그래밍 했다.

정답)

주제와 옵저버에서 모두 인터페이스를 사용했다. 111p

 

원칙3. 상속보다는 구성을 사용한다.

(힌트: 옵저버와 주제가 어떤 식으로 서로 협조하는지 생각해보자)

observer를 등록해놓고, 주제가 바뀌면 옵저버에 연락하는 식으로 협조한다.

observer를 주제에 상속하지 않았음?

정답) 111p

 

 

 

728x90
반응형