본문 바로가기

Design-Pattern

빨리 객체에게 연락해! 옵서버 패턴(observer pattern)

1. 옵서버 패턴(observer pattern) 이란?

옵서버(observer)를 번역해 보면 관측자란 뜻을 가지고 있습니다. 

주제 객체의 상태가 변하면 이를 주목하던 다른 객체들에게 바로 전달되는 특징을 가지고 있고.

이러한 상태는 여러가지로 정의할 수 있는데

1. 키보드나 마우스이 눌렸을 때

2. 버튼을 클릭했을때 등

등등 이벤트가 발생한다는 상황이라면 모두 적용할 수 있도록 다양합니다.

 

그림으로 이해해보면

옵저버 패턴 그림 이해도

이 정도로 표현이 가능하고

 

이러한 옵서버 패턴을 활용하면 다른 객체의 상태 변화를 별도의 함수 호출 없이 즉각적으로 알 수 있기 때문에, 

발생하는 이벤트에 대한 처리를 자주 해야 하는 프로그램이라면 매우 효율적인 프로그램을 작성할 수 있습니다.

 

이를 UML 다이어 그램으로 표현해보면 다음과 같습니다.

옵저버 패턴 UML 패턴

2. 옵서버 패턴(observer pattern) 특징?

이러한 옵저버 패턴의 가장 큰 특징은 느슨한 결합(Loose Coupling)인데 이는 주제와 옵서버가 서로 상호작용을 하긴 하지만 서로에 대해 잘 모르는 상황을 말합니다.

 

옵저버 패턴에서는 느슨한 결합을 통해서 다음과 같은 장점을 가지는데

 

1. 주제가 옵서버에 대해서 아는 것은 옵서버가 특정 인터페이스를 구현한다는 것뿐이다.

2. 옵서버는 언제든지 새로 추가할 수 있다.

3. 새로운 형식의 옵서버를 추가하려고 할 때도 주제를 전혀 변경할 필요가 없다.

4. 주제와 옵서버는 서로 독깁적으로 재사용할 수 있다.

5. 주제나 옵서버가 바뀌더라도 서로한테 영향을 미치지 않는다.

 

이러한 장점들로 인해 느슨한 결합을 이용한 옵서버 패턴은 변경하상이 생겨도 무난하게 처리 할수 있는 유연한 객체 지향 시스템을 구축할수 있습니다.

 

3. 옵서버 패턴(observer pattern) 구현?

이런 옵저버 패턴을 간단하게 구현해 보면 다음과 같다.

 

Example(클래스)

public class Example {
	public static void main(String[] args) {
		SimpleSubject simpleSubject = new SimpleSubject();
		SimpleObserver simpleObserver = new SimpleObserver(simpleSubject);
		simpleSubject.setValue(80);
		simpleSubject.removeObserver(simpleObserver);
	}
}

Observer(인터페이스)

public interface Observer {
	public void update(int value);
}

SimpleObserver(클래스)

public class SimpleObserver implements Observer {
	private int value;
	private Subject simpleSubject;

	public SimpleObserver(Subject simpleSubject) {
		this.simpleSubject = simpleSubject;
		simpleSubject.registerObserver(this);
	}
	public void update(int value) {
		this.value = value;
		display();
	}
	public void display() { System.out.println("Value: " + value); }
}

SimpleSubject(클래스)

import java.util.*;

public class SimpleSubject implements Subject {
	private List<Observer> observers;
	private int value = 0;
	
	public SimpleSubject() {
		observers = new ArrayList<Observer>();
	}
	
	public void registerObserver(Observer o) {
		observers.add(o);
	}
	
	public void removeObserver(Observer o) {
		observers.remove(o);
	}
	
	public void notifyObservers() {
		for (Observer observer : observers) {
			observer.update(value);
		}
	}
	
	public void setValue(int value) {
		this.value = value;
		notifyObservers();
	}
}

Subject(인터페이스)

public interface Subject {
	public void registerObserver(Observer o);
	public void removeObserver(Observer o);
	public void notifyObservers();
}