Observer

2 minute read

Observer Pattern

What’s Observer Pattern ?

  • 종속자(Dependent), 게시 - 구독(Publish - Subscribe) 이라고도 불림

  • 객체 사이에 일 대 다의 의존 관계를 정의해 두어, 어떤 객체의 상태가 변할 때 그객체에 의존성을 가진 다른객체들이 그 변화를 통지받고 자동으로 갱신 될 수 있게 만듭니다.
  • 주체는 독립된 여러 개의 감시가 있을 수 있습니다. 모든 감시자주체의 상태 변화가 있을 때마다 이 변하를 통보받습니다. 각 감시자는 주체의 상태와 자신의 상태를 동기화 시키기 위해 주체의 상태를 알아봅니다.

Purpose

  • 용도

    • 한 객채에 가해진 변경으로 다른객체를 변경해야 하고, 프로그래머들은 얼마나 많은 객체들이 변경되어야 하는지 몰라도 될때
  • 어떤 객체가 다른 객체에 자신의 변화를 통보할 수 있는데, 그변화에 관심있어 하는 객체들이 누구인지에 대한 가정 없이도 그러한 통보가 될때

    뉴스 - 구독자 옵저버 패턴
    뉴스머신 Subject
    구독자 Observer
    뉴스머신이 상태를 알리는 행위 notifyObserver()
    구독자가 상태를 갱신하는 행위 update()

UML

observer 패턴에 대한 이미지 검색결과

​ 옵저버 패턴의 기본 UML 다이어그램

img

​ 옵저버 패턴으로 설계한 구독(Publish - Subscribe) UML 다이어그램


Example

// 1. Observer 인터페이스 정의하기
// 정기구독자 및 이벤트 구독자가 아래의 인터페이스를 구현한다.
public interface Observer { 
    public void update(String title, String news); 
}
// 2. Publisher 인터페이스 정의
// 뉴스머신이 아래의 인터페이스를 구현한다.
public interface Publisher { 
    public void add(Observer observer); 
    public void delete(Observer observer); 
    public void notifyObserver(); 
}
// 3. Publisher 인터페이스를 구현하는 NewsMachine 클래스 정의
public class NewsMachine implements Publisher {
	private ArrayList<Observer> observers;
	private String title;
	private String news;
	
	public NewsMachine() {
		observers = new ArrayList<>();
	}

	@Override
	public void add(Observer observer) { // 새로운 구독자를 추가하는 메소드
		observers.add(observer);
	}

	@Override
	public void delete(Observer observer) { // 구독자를 삭제하는 메소드
		int index = observers.indexOf(observer);
		observers.remove(index);
	}

	@Override
	public void notifyObserver() { // 구독자들에게 뉴스를 통보하는 메소드
		for(Observer observer : observers) {
			observer.update(title, news);
		}
	}
	
	public void setNewsInfo(String title, String news) { // 뉴스를 저장하는 메소드
		this.title = title;
		this.news = news;
		notifyObserver();
	}

	public String getTitle() {
		return title;
	}

	public String getNews() {
		return news;
	}
}
// 4. AnnualSubscriber 클래스 정의
// Observer 인터페이스를 상속하여 만든 매년구독자 클래스입니다. Publisher 인터페이스를 구현한 클래스에서 Observer 인터페이스의 update()메소드를 호출 하게되면 자신이 구현한 메소드를 호출합니다.
public class AnnualSubscriber implements Observer { 
    private String newsString; 
    private Publisher publisher;
    
    public AnnualSubscriber(Publisher publisher) { 
        this.publisher = publisher; 
        publisher.add(this); 
    } 
    
    @Override 
    public void update(String title, String news) {
        this.newsString = title + " \n -------- \n " + news; display(); 
    } 
    
    private void display() { 
        System.out.println("\n\n오늘의 뉴스\n============================\n\n" + newsString); 
    }
}
// 5. EventSubscriber 클래스 정의
// Observer 인터페이스를 상속하여 만든 이벤트구독자 클래스입니다. Publisher 인터페이스를 구현한 클래스에서 Observer 인터페이스의 update()메소드를 호출 하게되면 자신이 구현한 메소드를 호출합니다.
public class EventSubscriber implements Observer { 
    private String newsString; 
    private Publisher publisher; 
    
    public EventSubscriber(Publisher publisher) {
        this.publisher = publisher; 
        publisher.add(this); 
    } 
    
    @Override public void update(String title, String news) {
        newsString = title + "\n------------------------------------\n" + news; 
        display(); 
    } 
    
    public void display() { 
        System.out.println("\n\n=== 이벤트 유저 ==="); 
        System.out.println("\n\n" + newsString); 
    } 
}
    
public class MainClass { 
    public static void main(String[] args) { 
        NewsMachine newsMachine = new NewsMachine(); 
        AnnualSubscriber as = new AnnualSubscriber(newsMachine); 
        EventSubscriber es = new EventSubscriber(newsMachine); 
        newsMachine.setNewsInfo("오늘 한파", "전국 영하 18도 입니다."); 
        newsMachine.setNewsInfo("벛꽃 축제합니다", "다같이 벚꽃보러~"); 
    } 
}

img

참고

https://flowarc.tistory.com/entry/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-%EC%98%B5%EC%A0%80%EB%B2%84-%ED%8C%A8%ED%84%B4Observer-Pattern

Updated: