갱스터가 경찰과 갱스터 영화에서 어떻게 협력했는지 아직도 기억하십니까? 갱단이 강도 일 때, 한두 사람이 항상 문에서 바람을 타십시오. 움직임이 있으면 내부 공범자에게 즉시 긴급하게 퇴각하도록 알립니다. 아마도 뉴스에 반드시 그 공범을 알리는 사람은 아마도 그 소식을 반드시 알지 못할 것입니다. 그리고 뉴스를 보낸 사람을 모르는 새로운 남동생이있을 수 있습니다. 그러나 이것은 아무것도 아닙니다. 동의 한 코드가 있기 때문에 통신에 영향을 줄 수 없습니다.
하하, 에어 벤터와 위에서 언급 한 도둑의 관계는 실제로 관찰자 패턴의 살아있는 예입니다.
옵저버 모드는 게시/구독 모드라고도합니다. GOF는 옵저버 패턴을 다음과 같이 정의합니다. 객체 간의 일대일 의존성을 정의합니다. 객체의 상태가 변경되면 이에 의존하는 모든 객체에 알림을 받고 자동으로 업데이트됩니다.
여기서는 먼저 객체 지향 디자인의 중요한 원리 인 단일 책임 원리에 대해 이야기 할 것입니다. 따라서 시스템의 각 객체는 문제 영역의 개별 추상화에 중점을 두어야합니다. 따라서 이상적으로는 물체는 한 가지만 수행합니다. 이것은 개발에 많은 이점을 제공합니다. 재사용 성과 유지 보수를 제공하며 리팩토링을위한 좋은 기초이기도합니다.
따라서 거의 모든 설계 패턴은이 기본 설계 원칙을 기반으로합니다. 관찰자 모델의 기원은 GUI 및 비즈니스 데이터 처리에 있어야한다고 생각합니다. 관찰자 모델을 설명하는 대부분의 예가이 주제이기 때문입니다. 그러나 관찰자 모드의 적용은 결코 이러한 측면에 국한되지 않습니다.
글쎄, 정의에 대한 이해는 항상 인스턴스를 분석해야합니다. WeChat 서비스 계정은 요즘 매우 인기가 있습니다. WeChat 서비스 계정의 배경으로 관찰자 모델을 소개하겠습니다.
사진 봐 :
각 사용자는 위 그림에 3 줄이 있으며 그림을 명확하게하기 위해 생략됩니다.
위의 그림에서 볼 수 있듯이 서비스 번호는 테마이고 사용자는 관찰자입니다. 이제 다음 기능을 명확히합니다.
1. 서비스 계정은 주제이며 비즈니스는 메시지를 추진하고 있습니다.
2. 관찰자는 주제를 구독하면되며 새로운 뉴스가있는 즉시 보내집니다.
3.이 주제 메시지를 원하지 않을 때 구독 취소
4. 서비스 계정이 여전히 존재하는 한 누군가가 구독하게됩니다. 이제 관찰자 패턴의 클래스 다이어그램을 살펴 보겠습니다.
다음은 코드 시간입니다. WeChat 3D 복권 서비스 계정과 일부 가입자를 시뮬레이션합니다.
먼저 주제 인터페이스 및 관찰자 인터페이스에 대한 글을 쓰기 시작하십시오.
패키지 com.zhy.pattern.observer; / ** * 주제 인터페이스, 모든 주제는이 인터페이스를 구현해야합니다 * @Author Zhy */ public interface 주제 {/ ** * 관찰자 등록 * * @param 옵저버 */ public void registerObserver (Observer Observer); / ** * 관찰자 제거 * * @Param Observer */ public void removeObserver (Observer Observer); / *** 모든 관찰자에게 알림*/ public void notifyObservers (); } package com.zhy.pattern.observer; / *** @author zhy 모든 관찰자는이 인터페이스를 구현해야합니다*/ public interface observer {public void update (String MSG); }다음 3D 서비스 번호 구현 클래스 :
패키지 com.zhy.pattern.observer; java.util.arraylist 가져 오기; Java.util.list 가져 오기; 공개 클래스 Objectfor3d는 주제 {private list <secerver> inservers = new ArrayList <Secterver> (); / *** 3D 복권 번호*/ 개인 문자열 msg; @override public void regis } @override public void removeObserver (Observer Observer) {int index = inservers.indexof (옵저버); if (index> = 0) {Observers.remove (index); }} @override public void notifyobservers () {for (Observer Observer : Observers) {Observer.update (msg); }} / ** * 주제 업데이트 메시지 * * @param msg * / public void setmsg (String msg) {this.msg = msg; NotifyObservers (); }}두 사용자 시뮬레이션 :
패키지 com.zhy.pattern.observer; 공개 클래스 옵저버1은 관찰자 (개인 주제 주제)를 구현합니다. public Observer1 (주제 주제) {this.subject = 대상; groudr.registerobserver (this); } @override public void update (string msg) {system.out.println ( "Observer1이 3D 번호를 가져옵니다 ->" + msg + ", 나는 그것을 기록하고 싶습니다."); }} 패키지 com.zhy.pattern.observer; 공개 클래스 옵저버2는 관찰자 (개인 주제 주제)를 구현합니다. public Observer2 (주제 주제) {this.subject = 주제; groudr.registerobserver (this); } @override public void update (string msg) {system.out.println ( "관찰자 2는 3D 번호를 가져옵니다 ->" + msg + "룸메이트를 말하고 싶습니다."); }} 메시지를 구독 한 모든 사용자가 서비스 계정에 유지 관리되며 서비스 계정에 새 메시지가있을 때 모든 사용자에게 알림을받습니다. 전체 아키텍처는 느슨한 커플 링이며 테마의 구현은 사용자에 의존하지 않습니다. 새 사용자가 추가되면 테마 코드를 변경할 필요가 없습니다. 사용자가 처리하는 방법 획득 한 데이터는 테마와 관련이 없습니다.
마지막으로 테스트 코드를보십시오.
package com.zhy.pattern.observer.test; com.zhy.pattern.observer.objectfor3d import; com.zhy.pattern.observer.observer 가져 오기; import com.zhy.pattern.observer.observer1; import com.zhy.pattern.observer.observer2; com.zhy.pattern.observer.subject import; 공개 클래스 테스트 {public static void main (string [] args) {// 3D 서비스 번호 시뮬레이션 ObjectFor3d gourthfor3d = new Objectfor3d (); // customer1 Observer Observer1 = new Observer1 (subjectfor3d); 옵저버 Observer2 = New Observer2 (subjectfor3d); griessFor3d.setmsg ( "20140420의 3D 숫자는 127"); griessFor3d.setmsg ( "20140421의 3D 숫자는 : 333"); }}출력 결과 :
Observer1은 3D 숫자를 얻습니다 -> 20140420의 3D 숫자는 다음과 같습니다. 127, 나는 그것을 적어두고 싶습니다. Observer2는 3D 숫자를 얻습니다 -> 20140420의 3D 숫자는 다음과 같습니다. 127 룸메이트에게 말하고 싶습니다. Observer1은 3D 숫자를 얻습니다 -> 20140421의 3D 숫자는 다음과 같습니다. 333, 나는 그것을 적어두고 싶습니다. Observer2는 3D 숫자를 얻습니다 -> 20140421의 3D 숫자는 다음과 같습니다. 333 룸메이트에게 말하고 싶습니다.
JDK 또는 Andorid에는 xxxview.addxxxlistenter와 같은 관찰자 모드를 구현하는 많은 장소가 있습니다. 물론 XXXView.setOnxxxListener는 옵저버 모드가 일대일 관계이기 때문에 반드시 관찰자 모드는 아닙니다. setxxxlistener의 경우 1 대 1 관계이며 콜백이라고해야합니다.
관찰자 모드 학습을 축하합니다. 위의 옵저버 모드를 통해 처음부터 쓸 수 있습니다. 물론 Java는 java.util.observable 및 java.util.observer의 도움으로 관찰자 모드를 구현하는 데 도움이되었습니다.
아래에서는 Java 내장 클래스를 사용하여 관찰자 패턴을 구현합니다.
우선, 3D 복권 서비스 번호 테마가 있습니다.
패키지 com.zhy.pattern.observer.java; java.util.observable import; 공개 클래스 주제는 관찰 가능한 {private string msg; 공개 문자열 getmsg () {return msg; } / ** * 주제 업데이트 메시지 * * @param msg * / public void setmsg (String msg) {this.msg = msg; setChanged (); NotifyObservers (); }}다음은 이중 컬러 볼 서비스 번호의 주제입니다.
패키지 com.zhy.pattern.observer.java; java.util.observable import; 공개 클래스 주제는 관찰 가능한 {private string msg; 공개 문자열 getmsg () {return msg; } / ** * 주제 업데이트 메시지 * * @param msg * / public void setmsg (String msg) {this.msg = msg; setChanged (); NotifyObservers (); }}마지막으로 사용자 :
패키지 com.zhy.pattern.observer.java; java.util.observable import; import java.util.observer; 공개 클래스 옵저버1은 관찰자 {public void registerSubject (Observable Observable) {verietable.addoBserver (this); } @override public void update (Observable O, Object Arg) {if (o instorctor3d) {giversityfor3d giverfor3d = (subjectfor3d) o; System.out.println ( "giversityfor3d의 msg->" + gourdefor3d.getmsg ()); } if (o indestionof subjectforssq) {giversityforssq subjectforssq = (subjectforssq) o; System.out.println ( "giversityforssq 's msg->" + gourdeforssq.getmsg ()); }}}테스트 코드보기 :
패키지 com.zhy.pattern.observer.java; 공개 클래스 테스트 {public static void main (string [] args) {subjectfor3d subjectfor3d = new subjectfor3d (); subjectforssq subjectforssq = new subjectforssq (); Observer1 Observer1 = New Observer1 (); Observer1.registersubject (griessFor3d); Observer1.registersubject (subjectforssq); griessFor3d.setmsg ( "Hello 3d'nums : 110"); istureforssq.setmsg ( "ssq'nums : 12,13,31,5,3 15"); }}테스트 결과 :
Subjectfor3d의 MSG-> hello 3d'nums : 110 SubjectForsSQ의 MSG-> SSQ'Nums : 12,13,31,5,4,3 15
Java 내장 클래스를 사용하여 관찰자 패턴을 구현하면 코드가 간결합니다. 그건 그렇고, AddoBserver, RemoveObserver, NotifyObservers가 우리를 위해 구현되었습니다. 우리가 관찰 가능한 것을 볼 수있는 것은 인터페이스가 아니라 클래스입니다. 기본적 으로이 책은 Java의 디자인에 대한 부정적인 태도를 가지고 있습니다. Java의 내장 관찰자 패턴은 인터페이스 지향 프로그래밍의 원리를 위반한다고 생각합니다. 그러나 당신이 그것에 대해 생각한다면, 당신은 실제로 여기에 관찰자 패턴을 작성하고 있습니다 (우리 자신의 구현). 인터페이스 아이디어는 매우 좋지만 지금 많은 주제를 계속 추가하면 DDOBSERVER, removeObserver, 각 주제에 대한 알림 서버는 기본적으로 동일합니다. 인터페이스는 코드 재사용을 구현할 수 없으며 결합 모드를 사용 하여이 세 가지 방법을 재사용 할 수있는 방법이 없으므로 여기 에서이 세 가지 방법을 구현하는 것이 합리적이라고 생각합니다.