OOP/Design Pattern

[OOP] 옵저버 패턴(Observer Pattern)

IT록흐 2022. 11. 13. 22:39
반응형

디자인 패턴이란?

객체지향설계 과정에서 발생하는 문제들을 해결하기 위한 패턴(Pattern)

 

문제 상황

 

 

 

 

데이터를 가진 객체(Score)와 해당 데이터를 참조하는 객체(ScoreView)가 있다. 

 

예를 들면,

 

점수객체(Score)가 있고 점수를 나타내는 전광판 객체(ScoreView)가 있다. 점수가 변할 때, Score는 ScoreView의 update 메소드를 호출하므로써 이를 통보해야 한다. 그래야 전광판 객체의 점수가 바뀐다.

 

만약 점수 객체의 데이터를 모니터링하는 객체가 전광판 객체만 있다면 위 구조는 문제되지 않는다. 하지만 만약 데이터를 참조하는 객체가 많아진다면 Score객체는 어떻게 통보를 해야할까?

 

 

 

 

 

만약 이와 같이, 점수를 모니터링하는 객체들이랑 모두 강한 결합을 한다면 Score 객체는 비대해진다. 그러므로 ScoreView, ScoreMaxView, ScoreStaticsView 의 로직이 바뀐다면 Score도 덩달아 바뀔 수 밖에 없다. 이는 유지보수에 좋지 못하다. 

 

 

해결책

 

 

 

일단 모니터링 객체들을 Observer 인터페이스로 추상화한다.

 

 

 

 

그리고 Score 객체도 Subject 추상 클래스를 상속한다. Subject 클래스는 옵저버를 관리하는 클래스로 이를 상속한 Score 클래스는 옵저버 관리 기능을 갖추게 된다. 

 

옵저버를 추가(attach), 삭제(dettach), 통보(notifyObservers) 기능은 Subject에 구현되어 있으므로 Score 클래스는 이를 신경쓰지 않아도 된다. ScoreView, ScoreMaxView, ScoreStaticsView 는 Observer 단위로 통일되어 관리된다. 

 

 

코드

 

Subject 클래스 및 Observer 클래스

public abstract class Subject{
	private List<Observer> observers = new ArrayList<Observer>();

	// 옵저버 추가
	public void attach(Observer observer) {
		observers.add(observer);
	}

	// 옵저버 삭제
	public void detach(Observer observer) {
		observers.remove(observer);
	}

	// 옵저버 통보
	public void notifyObservers() {
		for(Observer observer : observers) {
			observer.update(); 
		}
	}
}

public interface Observer {
	public void update();
}

 

Score 클래스 

public class Score extends Subject {
	private List<Integer> scores = new ArrayList<Integer>();

	public void addScore(int score) {
		scores.add(score);
		notifyObservers(); // 옵저버들에게 통보
	}

	public List<Integer> getScores() {
		return scores;
	}
}

 

ScoreView 클래스 

public class ScoreView implements Observer {
	private Score score; //score 객체 참조
	
	public ScoreView(Score score){
		this.score = score;
	}
	
	public void update(){
		List<Integer> scores = score.getScores();
		display(scores);
	}

	public void display(List<Integer> scores){
		//display 로직
	}
}

 

Main 클래스 

public class Main{
	public static void main(String[] args) {
		Score score = new Score();

		// 옵저버 등록
		score.attach(new ScoreView(score));
		score.attach(new ScoreMaxView(score));
		score.attach(new ScoreStaticsView(score));

		// 데이터 추가와 함께 옵저버들에게 통보(notify)
		score.addScore(1);
	}
}

 

 

정리

 

장점)

데이터를 가진 Score 객체는 Subject 추상클래스를 상속하여 확장성 있게 여러 개의 옵저버에게 데이터 변경을 통보할 수 있다.

 

 


 

 

참고자료

 

JAVA 객체지향 디자인 패턴 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

 

반응형