관찰자 패턴
객체 간에 일대다 관계가 있는 경우 관찰자 패턴이 사용됩니다. 예를 들어, 개체가 수정되면 해당 종속 개체에 자동으로 알림이 전달됩니다. 관찰자 패턴은 행동 패턴입니다.
Introduction
의도: 객체 간의 일대다 종속 관계를 정의합니다. 객체의 상태가 변경되면 해당 객체에 종속된 모든 객체에 알림이 전송되고 자동으로 업데이트됩니다.
주요 해결 방법: 객체의 상태 변경을 다른 객체에 알리는 문제를 해결하고 높은 수준의 협업을 보장하기 위해 사용 편의성과 낮은 결합도를 고려합니다.
사용 시기: 객체(대상 객체)의 상태가 변경되면 모든 종속 객체(관찰자 객체)에 알림이 전송되고 브로드캐스트 알림이 발생합니다.
해결 방법: 객체 지향 기술을 사용하면 이러한 종속성이 약화될 수 있습니다.
키 코드: 추상 클래스에는 관찰자를 저장하는 ArrayList가 있습니다.
적용 예: 1. 경매가 진행되는 동안 경매인은 최고 입찰가를 확인한 후 다른 입찰자에게 입찰을 알립니다. 2. 서유기에서 오공은 보살에게 붉은 소년을 내놓으라고 요청했는데, 보살은 땅에 물을 뿌리고 늙은 거북이를 끌어당겼습니다. 그는 보살이 물을 뿌리는 행위를 관찰했습니다.
이점: 1. 관찰자와 관찰 대상은 추상적으로 결합됩니다. 2. 트리거 메커니즘을 설정합니다.
단점: 1. 관찰 대상에 직접 및 간접 관찰자가 많은 경우 모든 관찰자에게 알리는 데 많은 시간이 걸립니다. 2. 관찰자와 관찰 대상 사이에 순환 종속성이 있는 경우 관찰 대상은 둘 사이의 순환 호출을 트리거하여 시스템 충돌을 일으킬 수 있습니다. 3. 관찰자 모드에는 관찰 대상 개체가 어떻게 변경되었는지 관찰자가 알 수 있도록 하는 해당 메커니즘이 없고 관찰 대상이 변경되었다는 것만 알 수 있습니다.
사용 시나리오: 1 동일한 논리를 가진 여러 하위 클래스에 공통된 메서드가 있습니다. 2. 중요하고 복잡한 방법은 템플릿 방법으로 간주될 수 있습니다.
참고: 1. JAVA에는 이미 관찰자 패턴에 대한 지원 클래스가 있습니다. 2. 순환 참조를 피하십시오. 3. 순차적으로 실행할 경우 관찰자 오류로 인해 시스템이 정지되는 현상이 발생하며 일반적으로 비동기식 방식을 사용합니다.
Implementation
Observer 패턴은 Subject, Observer 및 Client의 세 가지 클래스를 사용합니다. Subject 개체에는 관찰자를 Client 개체에 바인딩하거나 바인딩을 해제하는 메서드가 있습니다. Subject 클래스, Observer 추상 클래스 및 추상 클래스 Observer를 확장하는 엔터티 클래스를 만듭니다.
ObserverPatternDemo, 데모 클래스는 Subject 및 엔터티 클래스 개체를 사용하여 관찰자 패턴을 보여줍니다.
1단계
Subject 클래스를 만듭니다.
Subject.java
import java.util.ArrayList; import java.util.List; public class Subject { private List<Observer> observers = new ArrayList<Observer>(); private int state; public int getState() { return state; } public void setState(int state) { this.state = state; notifyAllObservers(); } public void attach(Observer observer){ observers.add(observer); } public void notifyAllObservers(){ for (Observer observer : observers) { observer.update(); } } }
2단계
Observer 클래스를 생성합니다.
Observer.java
public abstract class Observer { protected Subject subject; public abstract void update(); }
3단계
엔티티 관찰자 클래스를 만듭니다.
BinaryObserver.java
public class BinaryObserver extends Observer{ public BinaryObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) ); } }
OctalObserver.java
public class OctalObserver extends Observer{ public OctalObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Octal String: " + Integer.toOctalString( subject.getState() ) ); } }
HexaObserver.java
public class HexaObserver extends Observer{ public HexaObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() ); } }
4단계
Subject 및 엔터티 관찰자 개체를 사용합니다.
ObserverPatternDemo.java
public class ObserverPatternDemo { public static void main(String[] args) { Subject subject = new Subject(); new HexaObserver(subject); new OctalObserver(subject); new BinaryObserver(subject); System.out.println("First state change: 15"); subject.setState(15); System.out.println("Second state change: 10"); subject.setState(10); } }
5단계
출력을 확인합니다.
rreee