상세 컨텐츠

본문 제목

옵저버패턴(Observer Pattern)

Spring/디자인패턴

by Chan.94 2022. 8. 15. 14:08

본문

반응형

옵저버 패턴(Observer Pattern)

옵저버패턴이란 객체의 상태 변화를 관찰하는 관찰자(옵저버)들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 객체가 직접 등록된 각각의 옵저버에게 통지하도록 하는 디자인 패턴이다.

 

다이어그램

 

  • Observer
    - 데이터의 변경을 통보 받는 인터페이스
    - Subject에서는 Observer 인터페이스의 update 메서드를 호출함으로써 ConcreteSubject의 데이터 변경을 ConcreteObserver에게 통보함
  • Subject
    - ConcreteObserver 객체를 관리하는 요소
    - Observer 인터페이스를 참조해서 ConcreteObserver를 관리
  • ConcreteSubject
    - 변경 관리 대상이 되는 데이터가 있는 클래스(통보하는 클래스)
    - 데이터 변경을 위한 메서드인 setContent가 있다.
    - setContent 메서드에서는 자신의 데이터인 content를 변경하고 Subject의 notifyObservers 메서드를 호출해서 ConcreteObserver 객체에 변경을 통보한다.
  • ConcreteObserver
    - ConcreteSubject의 변경을 통보받는 클래스
    - Observer 인터페이스의 nofify메서드를 구현함으로써 변경을 통보받는다.

옵저버 패턴 예시

ex) 1~N까지 숫자가 증가할 때 해당 숫자가 3의 배수, 5의 배수인 경우 이벤트가 발생된다.


Observer 인터페이스

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

Subject 인터페이스

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

Event 인터페이스

public interface ActionEvent {
	public void action();
}

 

Observer들이 상속받는 인터페이스로 다이어그램의 display() 메소드를 구현하기 위함.

 

 

Observer 객체

public class Multiple3Counting implements Observer, ActionEvent {
	private int number;
	private NumberCounting numberCounting;

	public Multiple3Counting(NumberCounting numberCounting) {
		this.numberCounting = numberCounting;
		numberCounting.registerObserver(this);
	}
	
	@Override
	public void action() {
		System.out.println("[3]	MultipleCounting number : " + number);
	}

	@Override
	public void update(int number) {
		this.number = number;
		
		if(number % 3 == 0) {
			action();
		}
	}

}

public class Multiple5Counting implements Observer, ActionEvent {
	private int number;
	private NumberCounting numberCounting;

	public Multiple5Counting(NumberCounting numberCounting) {
		this.numberCounting = numberCounting;
		numberCounting.registerObserver(this);
	}
	
	@Override
	public void action() {
		System.out.println("[5]	MultipleCounting number : 	" + number);
	}

	@Override
	public void update(int number) {
		this.number = number;
		
		if(number % 5 == 0) {
			action();
		}
	}

}

 

Subject 객체

public class NumberCounting implements Subject {
	private List<Observer> observers;
	int number;
	
	public NumberCounting() {
		observers = new ArrayList<Observer>();
	}

	@Override
	public void registerObserver(Observer o) {
		observers.add(o);
	}

	@Override
	public void removeObserver(Observer o) {
		observers.remove(o);
	}

	@Override
	public void notifyObservers() {
		for (Observer observer : observers) {
			observer.update(number);
		}
	}
	
	public void numberChanged() {
		notifyObservers();
	}
	
	public void setNumber(int number) {
		this.number = number;
		numberChanged();
	}

	public int getNumber() {
		return number;
	}

}

 

Main

public class ObserverMain {

	public static void main(String[] args) {
		NumberCounting numberCounting = new NumberCounting();
		
		Multiple3Counting multiple3Counting = new Multiple3Counting(numberCounting);
		Multiple5Counting multiple5Counting = new Multiple5Counting(numberCounting);
		
		for(int number = 0 ; number <= 10 ; number++) {
			numberCounting.setNumber(number);
		}
		
		System.out.println("#########removeObserver#########");
		numberCounting.removeObserver(multiple5Counting);

		
		for(int number = 0 ; number <= 10 ; number++) {
			numberCounting.setNumber(number);
		}
	}

}

 

실행결과

[3]	MultipleCounting number : 0
[5]	MultipleCounting number : 	0
[3]	MultipleCounting number : 3
[5]	MultipleCounting number : 	5
[3]	MultipleCounting number : 6
[3]	MultipleCounting number : 9
[5]	MultipleCounting number : 	10
#########removeObserver#########
[3]	MultipleCounting number : 0
[3]	MultipleCounting number : 3
[3]	MultipleCounting number : 6
[3]	MultipleCounting number : 9

 

느슨한 결합(Loose Coupling)

두 객체가 느슨하게 결합되어 있다는 것은, 그 둘이 상호작용을 하긴 하지만 서로에 대해 잘 모르는 것을 의미합니다. 

옵저버 패턴에서는 주제와 옵저버가 느슨하게 결합되어 있는 객체 디자인을 제공합니다.

장점

1. 옵저버를 언제든 새로 추가, 제거할 수 있다.
2. 새로운 형식의 옵저버라 할 지라도 주제를 전혀 변경할 필요가 없다.
3. 주제와 옵저버는 서로 독립적으로 재사용할 수 있다.
4. 주제나 옵저버가 바뀌더라도 서로에게 영향을 미치지 않는다.

 

옵저버 패턴의 장단점

장점
1. 실시간으로 한 객체의 변경사항을 다른 객체에 전파할 수 있습니다.
2. 느슨한 결합으로 시스템이 유연하고 객체 간의 의존성을 제거할 수 있다.

단점
1. 너무 많이 사용하게 되면, 상태 관리가 힘들 수 있습니다

 


[Spring & Spring Boot/디자인패턴] - 디자인 패턴 정리

반응형

관련글 더보기

댓글 영역

>