CS

옵저버(Observer ) 패턴 개념 및 구현 방법(Java, JavaScript)

cob 2023. 1. 10. 15:31

 

Observer Pattern

 

옵저버 패턴(Observer Pattern)이란?
주체가 어떤 객체의 상태 변화를 관찰하다가 상태 변화가 있을 때마다 메서드 등을 통해 옵저버 목록에 있는 옵저버들에게 변화를 알려주는 디자인 패턴이다. 여기서 주체란 객체 상태 변화를 보고 있는 관찰자이며, 옵저버들이란 이 객체의 상태 변화에 따라 전달되는 메서드 등을 기반으로 ‘추가 변화 사항’이 생기는 객체들을 의미한다.

 

 

 

 

 


1. 옵저버 패턴 구조

1-1) 객체와 주체가 분리

객체와 주체가 분리되어 있는 옵저버 패턴

 

 

1-1) 객체와 주체가 합쳐짐

객체와 주체가 합쳐진 옵저버 패턴

 

 

 


2. 옵저버 패턴의 사용 예

2-1) 옵저버 패턴을 활용한 서비스로는 트위터가 있다.

  • 내가 어떤 사람인 주체를 ‘팔로우’했다면, 주체가 포스팅을 올리게 되면 알림이 ‘팔로워’에게 간다.

 

2-2) 옵저버 패턴은 주로 이벤트 기반 시스템에 사용하며 MVC(Model-View-Controller) 패턴에도 사용된다. 

  • 주체(관찰자)라고 볼 수 있는 모델(model)에서 변경 사항이 생겨 update() 메서드로 옵저버인 뷰에 알려주고, 이를 기반으로 컨트롤러(controller)등이 작동된다.

옵저버 패턴 MVC 구조도

 

 

 


3. Java에서 옵저버 패턴 구현

import java.util.ArrayList;
import java.util.List;

interface Subject {
	public void register(Obsever obj);
	public void unregistere(Obsever obj);
	public void notifyObservers();
	public Object getUpdate(Observer obj);
}
interface Observer {
	public void update();
}
class Topic implements Subject {
	private List<Observer> observers;
	private String message;
	
	public Topic() {
		this.observers = new ArrayList<>();
		this.message = "";
	}

	@Override
	public void register(Observer obj) {
		if(!observers.contains(obj)) observers.add(obj);
	}

	@Override
	public void unregister(Observer obj) {
		observers.remove(obj);
	}
	
	@Override
	public void notifyObservers() {
		this.observers.forEach(Observer::update);
	}

	@Override
	public Object getUpdate(Observer obj) {
		return this.message;
	}

	public void postMessage(String msg) {
		System.out.println("Message sended to Topic: " + msg);
		this.message = msg;
		notifyObservers();
	}
}

class TopicSubscriber implements Observer {
	private String name;
	private String topic;

	public TopicSubscriber(String name, Subject topic) {
		this.name = name;
		this.topic = topic;
	}

	@Override
	public void update() {
		String msg = (String) topic.getUpdate(this);
		System.out.println(name + ":: got message >> " + msg);
	}
}

public class HelloWorld {
	public static void main(Stirng[] args) {
    // topic을 기반으로 옵저버 패턴 구현 (topic은 주체이자 객체)
		Topic topic = new Topic();
   
    // 옵저버를 선언할 때 해당 이름과 어떠한 토픽의 옵저버가 될것인지 정한다.
		Observer a = new TopicSubscriber("a", topic);
		Observer b = new TopicSubscriber("b", topic);
		Observer c = new TopicSubscriber("c", topic);
		topic.register(a);
		topic.register(b);
		topic.register(c);

		topic.postMessage("amumu is op champion!!");
		/*
			a:: got message >> amumu is op champion!!
			b:: got message >> amumu is op champion!!
			c:: got message >> amumu is op champion!!
		*/
	}
}

 

 

 

 


4. JavaScript에서 옵저버 패턴 구현

자바스크립트에서의 옵저버 패턴은 프록시 객체를 통해 구현할 수도 있다.

2023.01.09 - [JavaScript] - 프록시(Proxy) 객체 JavaScript에서 사용 방법(옵저버 패턴)

 

 

 

반응형