정의 : 객체 간의 일대일 종속성을 정의하여 각 객체가 상태를 변경하면 그에 의존하는 모든 객체가 알림을 받고 자동으로 업데이트됩니다.
유형 : 행동 패턴
클래스 다이어그램 :
소프트웨어 시스템에는 종종 필요가 있습니다. 객체의 상태가 변경되면 이와 관련된 일부 객체도 그에 따라 변경됩니다. 예를 들어 마우스 오른쪽 버튼 클릭 메뉴 기능을 설계하려고합니다. 소프트웨어의 유효 영역을 마우스 오른쪽 버튼으로 클릭하는 한 메뉴가 나타납니다. 예를 들어, 파일이 수정되는 한 Eclipse가 개발 될 때와 같이 자동 배포 기능을 설계하려고합니다. Eclipse는 수정 된 파일을 서버에 자동으로 배포합니다. 이 두 기능 사이에는 유사성이 있습니다. 즉, 하나의 객체는 항상 다른 객체를 모니터링해야하며 상태가 변경되는 한 해당 작업이 필요합니다. 실제로,이를 달성 할 수있는 많은 솔루션이 있지만, 관찰자 모델을 사용하는 것은 의심 할 여지없이 주류 선택입니다.
관찰자 패턴의 구조
가장 기본적인 관찰자 모드에서 다음 4자가 포함됩니다.
관찰자 : 클래스 다이어그램에서 클래스에 관찰자 객체를 저장하는 벡터 컨테이너가 있음을 알 수 있습니다 (목록 대신 벡터가 사용되는 이유는 멀티 스레드 작업이있을 때 벡터가 안전하고 목록은 안전하지 않기 때문입니다). 이 벡터 컨테이너는 관찰자 클래스의 핵심입니다. 세 가지 다른 방법이 있습니다. 첨부 방법은이 컨테이너에 관찰자 객체를 추가하는 것입니다. 분리 방법은 컨테이너에서 관찰자 물체를 제거하는 것입니다. 알림 메소드는 관찰자 객체의 해당 메소드를 차례로 호출하는 것입니다. 이 역할은 인터페이스, 추상 클래스 또는 구체적인 클래스 일 수 있습니다. 많은 경우 다른 패턴과 혼합되므로 추상 클래스를 사용하는 경우가 더 많기 때문입니다.
관찰자 : 관찰자 역할은 일반적으로 인터페이스이며, 이는 하나의 업데이트 방법 만 있습니다. 관찰자 상태가 변경되면이 방법이 호출됩니다.
특정 관찰자 :이 역할은 쉬운 확장에 사용되며 특정 비즈니스 논리는이 역할에서 정의 될 수 있습니다.
특정 관찰자 : 관찰자 인터페이스의 특정 구현. 이 역할에서, 대상의 상태가 변경 될 때 처리 될 논리가 처리 될 때.
옵저버 모드 구현 예
제목 인터페이스
공개 인터페이스 주제 {public void registerObserver (Observer O); 공개 void removeObserver (Observer o); 공개 void notifyallobservers ();}관찰자 인터페이스
공개 인터페이스 옵저버 {public void update (주제);}헌터 클래스는 주제 인터페이스를 구현합니다
java.util.arraylist 가져 오기; 공개 클래스 헤드 헌터는 주제를 구현 {// Mike, Bill 등과 같은 사용자 목록을 정의합니다. Private ArrayList <Secterver> userList; 개인 Arraylist <string> 작업; public Headhunter () {userList = new ArrayList <Secterver> (); jobs = new ArrayList <string> (); } @override public void registerObserver (Observer o) {userList.Add (o); } @override public void removeObserver (Observer o) {} @override public void notifyAllObServers () {for (Observer O : userList) {O.Update (this); }} public void addjob (문자열 작업) {this.jobs.add (job); notifyallobservers (); } public arraylist <string> getJobs () {return jobs; } public String toString () {return jobs.toString (); }}Jobseeker는 관찰자입니다.
공개 클래스 구직자는 관찰자 {개인 문자열 이름; 공개 구직자 (문자열 이름) {this.name = 이름; } @override public void update (주제) {system.out.println (this.name + "got notified!"); // 인쇄 작업 목록 System.out.println (s); }}시작 :
Public Class Main {public static void main (String [] args) {Headhunter HH = New Headhunter (); hh.registerobserver (New Jobseeker ( "Mike")); hh.registerobserver (New Jobseeker ( "Chris")); hh.registerobserver (New Jobseeker ( "Jeff")); // 작업을 추가 할 때마다 모든 작업에 알릴 수 있습니다. hh.addjob ( "Google Job"); hh.addjob ( "야후 작업"); }} 관찰자 모드의 장점
관찰자와 관찰자는 약간 관련되어 있으며 추상적으로 결합되어 두 가지 모두에 대해 더 쉽게 확장 할 수 있습니다.
관찰자 모드는 일반적으로 사용되는 트리거 메커니즘으로 트리거 체인을 형성하고 각 관찰자의 방법을 차례로 처리합니다. 그러나 동시에, 이것은 또한 관찰자 모드의 단점이기도합니다. 체인에서 트리거되므로 관찰자가 많을 때 성능 문제가 더 걱정됩니다. 또한, 체인 구조에서, 원형 기준 오류가 발생할 가능성이 높아서 시스템이 위조 될 수있다.
요약
Java 언어에는 인터페이스 관찰자와 구현 클래스가 관찰 가능하며 종종 관찰자 역할을 구현합니다. JDK API 문서 에서이 두 클래스의 사용 방법을 볼 수 있습니다.
VC ++, JavaScript DOM 또는 AWT 개발을 한 친구는 모두 이벤트 처리에 대해 놀랍습니다. 관찰자 패턴을 이해 한 후에, 그들은 이벤트 처리 메커니즘의 원리에 대한 특정 이해를 가지고 있습니다. 이벤트 트리거 프로세싱 메커니즘의 함수를 설계하려면 옵저버 모드를 사용하는 것이 좋습니다. AWT의 이벤트 처리 DEM (Delegation Event Model)은 관찰자 모드를 사용하여 구현됩니다.