옵저버 패턴
Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 87개 중 68번째.
Observer Pattern은 객체 간에 일대다 관계를 설정하는 행동 디자인 패턴입니다. 한 객체(subject)의 상태가 변경되면 모든 종속 객체(observers)에 자동으로 알림이 전송되고 업데이트됩니다. 뉴스레터 구독과 같다고 생각해 보세요. 새로운 콘텐츠가 게시될 때마다 구독자는 업데이트를 받습니다.
이 패턴은 두 가지 주요 구성 요소로 이루어집니다. 관찰자 목록을 유지하고 변경 사항을 관찰자에게 알리는 주체와, 알림에 응답하기 위한 업데이트 메서드를 정의하는 관찰자입니다.
import java.util.ArrayList;
import java.util.List;
interface Observer {
void update(String message);
}
class NewsPublisher {
private List<Observer> subscribers = new ArrayList<>();
public void subscribe(Observer observer) {
subscribers.add(observer);
}
public void unsubscribe(Observer observer) {
subscribers.remove(observer);
}
public void publish(String news) {
for (Observer subscriber : subscribers) {
subscriber.update(news);
}
}
}
class EmailSubscriber implements Observer {
private String email;
public EmailSubscriber(String email) {
this.email = email;
}
public void update(String message) {
System.out.println("Email to " + email + ": " + message);
}
}publisher가 뉴스를发布하면 모든 구독자에게 자동으로 알림이 전송됩니다:
NewsPublisher publisher = new NewsPublisher();
publisher.subscribe(new EmailSubscriber("alice@mail.com"));
publisher.subscribe(new EmailSubscriber("bob@mail.com"));
publisher.publish("Breaking news!");
// 출력:
// alice@mail.com으로 보낸 이메일: Breaking news!
// bob@mail.com으로 보낸 이메일: Breaking news!옵저버 패턴은 느슨한 결합을 촉진합니다. 주체는 옵저버의 구체 클래스가 무엇인지 알 필요 없이, 옵저버가 Observer 인터페이스를 구현한다는 것만 알면 됩니다. 따라서 주체를 수정하지 않고도 새로운 옵저버 유형을 쉽게 추가할 수 있습니다.
챌린지
쉬움Observer Pattern을 사용하여 주가 알림 시스템을 만들어 봅시다! 주가가 변경될 때마다 주식 시세 표시기가 여러 투자자에게 알림을 보내고, 각 투자자가 주가 업데이트에 자신만의 방식으로 반응하는 시스템을 만들게 됩니다.
코드를 네 개의 파일로 구성합니다:
Observer.java: 모든 투자자가 구현할Observerinterface를 Define합니다. 옵저버가 주가 변경에 대한 알림을 받는 데 사용하는 단일update(String stockName, double price)method를 Declare해야 합니다.StockTicker.java: 옵저버 목록을 유지하고 주가 변경을 알리는 subject class를 Create합니다.StockTicker에는 다음이 있어야 합니다:주식 이름을 위한 private String field (constructor를 통해 설정).
current price를 위한 private double field (initially 0).
구독한 옵저버를 저장할 private list.
옵저버를 목록에 추가하는
subscribe(Observer observer)method.옵저버를 목록에서 제거하는
unsubscribe(Observer observer)method.주가를 업데이트한 다음 주식 이름과 새 주가를 사용하여 각 옵저버의
updatemethod를 calling하여 모든 옵저버에게 알리는setPrice(double price)method.Investors.java:Observerinterface를 Implement하는 두 가지 서로 다른 투자자 유형을 Create합니다:DayTrader- constructor를 통해 설정되는 private name field를 가집니다. 업데이트되면[name] received alert: [stockName] is now $[price] - Making quick trade!를 출력합니다.LongTermInvestor- constructor를 통해 설정되는 private name field를 가집니다. 업데이트되면[name] received alert: [stockName] is now $[price] - Holding steady.를 출력합니다.주가를 소수점 이하 두 자리로 Format합니다.
Main.java: 옵저버 시스템을 하나로 결합합니다! 세 가지 inputs를 받습니다: 주식 이름(String), 첫 번째 주가 업데이트(double), 두 번째 주가 업데이트(double).given 주식 이름으로
StockTicker를 Create합니다."Alice"라는 이름의DayTrader와"Bob"이라는 이름의LongTermInvestor를 Create하고, 둘 다 시세 표시기에 subscribe합니다.주가를 첫 번째 input value로 설정합니다(모든 옵저버에게 알림). 그런 다음 Alice를 구독 해제합니다. 마지막으로 주가를 두 번째 input value로 설정합니다(이번에는 Bob에게만 알림이 전송되어야 합니다).
다음 순서로 세 가지 inputs를 받습니다: 주식 이름(String), 첫 번째 주가(double), 두 번째 주가(double).
이 challenge는 Observer Pattern의 강력함을 보여 줍니다. StockTicker는 특정 투자자 유형에 대해 아무것도 알지 못합니다. 단지 그들이 Observer를 Implement한다는 것만 알고 있습니다. Alice의 구독을 해제하면 Alice는 더 이상 업데이트를 받지 않지만 Bob은 계속 알림을 받습니다. 이러한 느슨한 결합 덕분에 시세 표시기를 변경하지 않고도 새로운 투자자 유형을 쉽게 추가할 수 있습니다!
직접 해보기
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 입력값 읽기
String stockName = scanner.nextLine();
double firstPrice = scanner.nextDouble();
double secondPrice = scanner.nextDouble();
// TODO: 주어진 주식 이름으로 StockTicker 생성하기
// TODO: "Alice"라는 이름의 DayTrader 생성하기
// TODO: "Bob"이라는 이름의 LongTermInvestor 생성하기
// TODO: Alice와 Bob 모두 ticker에 구독시키기
// TODO: 가격을 firstPrice로 설정하기 (두 옵저버 모두 알림을 받음)
// TODO: Alice 구독 해제하기
// TODO: 가격을 secondPrice로 설정하기 (Bob만 알림을 받음)
scanner.close();
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
4상속
상속의 기초 (extends)super 키워드메서드 오버라이딩 (@Override)생성자 체이닝Object 클래스단일 및 다중 레벨 상속다중 클래스 상속이 불가능한 이유요약 - 직원 계층 구조직접 연습해 보세요: 온라인 Java 컴파일러