日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java jdk 观察者模式_java观察者模式实现和java观察者模式演化

發(fā)布時(shí)間:2025/3/13 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java jdk 观察者模式_java观察者模式实现和java观察者模式演化 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

簡(jiǎn)單的觀察者模式實(shí)現(xiàn)

import java.util.ArrayList;

import java.util.Collections;

import java.util.Iterator;

import java.util.List;

/**

* 觀察者模式中用到了回調(diào):

* A. 觀察者將自己注冊(cè)到被觀察者的監(jiān)聽者列表,且觀察者類自身提供了一個(gè)回調(diào)函數(shù)

* B. 被觀察者(Observable或Subject)維護(hù)觀察者列表,并且可以注冊(cè)和解注冊(cè)觀察者

* C. 一旦被觀察者狀態(tài)發(fā)生改變,它可以調(diào)用notifyObservers(),這個(gè)方法將遍歷觀察者列表并逐個(gè)調(diào)用

觀察者提供的回調(diào)函數(shù)

* @author will

*

*/

public class SimpleObserverPattern {

public static void main(String[] args) {

SimpleObserverPattern sop = new SimpleObserverPattern();

List observers = new ArrayList ();

IObserver observerA = sop.new Observer("ObserverA");

IObserver observerB = sop.new Observer("ObserverB");

observers.add(observerA);

observers.add(observerB);

IObservable observable = sop.new Observable(observers);

observable.registerObserver(sop.new Observer("ObserverC"));

observable.changeState();

observable.close();

}

// 被觀察者,有的地方叫Subject

interface IObservable {

void registerObserver(IObserver observer);

void unregisterObserver(IObserver observer);

void notifyObservers();

String getState();

void changeState();

void close();

}

class Observable implements IObservable {

private static final String NEW = "New";

private static final String CHANGED = "Changed";

private static final String CLOSED = "Closed";

private String state;

private List observers;

public Observable() {

this(null);

}

public Observable(List observers) {

if(observers == null) {

observers = new ArrayList ();

}

this.observers = Collections.synchronizedList(observers);

this.state = NEW;

}

@Override

public void registerObserver(IObserver observer) {

observers.add(observer);

}

@Override

public void unregisterObserver(IObserver observer) {

observers.remove(observer);

}

@Override

public void notifyObservers() {

Iterator iter = observers.iterator();

while(iter.hasNext()) {

iter.next().update(this);

}

}

@Override

public String getState() {

return state;

}

@Override

public void changeState() {

this.state = CHANGED;

notifyObservers();

}

@Override

public void close() {

this.state = CLOSED;

notifyObservers();

}

}

interface IObserver {

void update(IObservable observalbe);

}

class Observer implements IObserver {

private String name;

public Observer(String name) {

this.name = name;

}

@Override

public void update(IObservable observalbe) {

System.out.println(

String.format("%s receive observalbe's change, current observalbe's state is %s",

name, observalbe.getState()));

}

}

}

上面的實(shí)現(xiàn)直接將被觀察者對(duì)象作為回調(diào)函數(shù)參數(shù),這樣做很不優(yōu)雅,在簡(jiǎn)單的場(chǎng)景可能奏效。

但事實(shí)上更多情況下,一個(gè)被觀察者有很多種事件或者狀態(tài),而每個(gè)觀察者可能感興趣的事件或狀態(tài)都不相同,或者為了信息隱藏的目的,不想讓每個(gè)觀察者都能訪問到Observable內(nèi)部的所有狀態(tài)。

這樣我繼續(xù)演化代碼為下面這個(gè)版本,注意我這里沒有很細(xì)致地考慮并發(fā)問題。

import java.util.Collections;

import java.util.HashSet;

import java.util.Hashtable;

import java.util.Iterator;

import java.util.Set;

public class MultiEventObserverPattern {

public static void main(String[] args) {

MultiEventObserverPattern meop = new MultiEventObserverPattern();

IObservable observable = meop.new Observable();

IObserver observerA = meop.new Observer("ObserverA");

IObserver observerB = meop.new Observer("ObserverB");

// 注冊(cè)感興趣的事件

observable.registerObserver(observable.getEventA(), observerA);

observable.registerObserver(observable.getEventB(), observerB);

// 改變被觀察者狀態(tài)

observable.changeStateA();

observable.changeStateB();

}

interface IEvent {

void eventChange();

String getState();

}

class EventA implements IEvent {

private static final String INITIALIZED = "Initialized";

private static final String PENDING = "Pending";

private String state;

public EventA() {

this.state = INITIALIZED;

}

@Override

public void eventChange() {

System.out.println("EventA change");

this.state = PENDING;

}

@Override

public String toString() {

return "EventA";

}

@Override

public String getState() {

return state;

}

}

class EventB implements IEvent {

private static final String NEW = "New";

private static final String IDLE = "Idle";

private String state;

public EventB() {

this.state = NEW;

}

@Override

public void eventChange() {

System.out.println("EventB change");

this.state = IDLE;

}

@Override

public String toString() {

return "EventB";

}

@Override

public String getState() {

return state;

}

}

// 被觀察者(Observable),有的地方叫Subject

interface IObservable {

void registerObserver(IEvent event, IObserver observer);

void unregisterObserver(IEvent event, IObserver observer);

// 通知觀察者某個(gè)事件發(fā)生了

void notifyObservers(IEvent event);

void changeStateA();

void changeStateB();

IEvent getEventA();

IEvent getEventB();

}

class Observable implements IObservable {

private IEvent eventA;

private IEvent eventB;

private Hashtable> eventObserverMapping;

public Observable() {

this(null);

}

// 這里如果evenObserverMapping傳入的某些Set是未被同步修飾的,那么也沒辦法

public Observable(Hashtable> eventObserverMapping) {

if(eventObserverMapping == null) {

eventObserverMapping = new Hashtable> ();

}

this.eventObserverMapping = new Hashtable> ();

this.eventA = new EventA();

this.eventB = new EventB();

}

@Override

public void registerObserver(IEvent event, IObserver observer) {

Set observers = eventObserverMapping.get(event);

if(observers == null) {

observers = Collections.synchronizedSet(new HashSet ());

observers.add(observer);

eventObserverMapping.put(event, observers);

}

else {

observers.add(observer);

}

}

@Override

public void unregisterObserver(IEvent event, IObserver observer) {

Set observers = eventObserverMapping.get(event);

if(observers != null) {

observers.remove(observer);

}

}

@Override

public void notifyObservers(IEvent event) {

Set observers = eventObserverMapping.get(event);

if(observers != null && observers.size() > 0) {

Iterator iter = observers.iterator();

while(iter.hasNext()) {

iter.next().update(event);

}

}

}

@Override

public void changeStateA() {

// 改變狀態(tài)A會(huì)觸發(fā)事件A

eventA.eventChange();

notifyObservers(eventA);

}

@Override

public void changeStateB() {

// 改變狀態(tài)B會(huì)觸發(fā)事件B

eventB.eventChange();

notifyObservers(eventB);

}

@Override

public IEvent getEventA() {

return eventA;

}

@Override

public IEvent getEventB() {

return eventB;

}

}

interface IObserver {

void update(IEvent event);

}

class Observer implements IObserver {

private String name;

public Observer(String name) {

this.name = name;

}

@Override

public void update(IEvent event) {

System.out.println(

String.format("%s receive %s's change, current observalbe's state is %s",

name, event, event.getState()));

}

}

}

似乎看起來挺完美了,但還是不夠完美。因?yàn)槭录挥簿幋a為被觀察者類的屬性。這樣事件類型在編譯時(shí)期就被定死了,如果要增加新的事件類型就不得不修改IObservable接口和Observable類,這大大削減了靈活性。

相當(dāng)于被觀察者耦合于這些具體的事件,那么我們?nèi)绾蝸泶蚱七@個(gè)限制呢?

答案是引入一個(gè)新的組件,讓那個(gè)組件來管理事件、觀察者、被觀察者之間的關(guān)系,事件發(fā)生時(shí)也由那個(gè)組件來調(diào)用觀察者的回調(diào)函數(shù)。這也是一種解耦吧,有點(diǎn)類似Spring的IOC容器。

至于具體實(shí)現(xiàn),我覺得Guava EventBus做得已經(jīng)蠻好了,可以參考我前面提到的鏈接。

PS:本帖不是為Guava EventBus做廣告,只是自己的思路一步步推進(jìn),逐漸地就和Guava EventBus的設(shè)計(jì)思路吻合了。

下面繼續(xù)看看JDK標(biāo)準(zhǔn)類實(shí)現(xiàn)觀察者模式的例子,然后分析下它的源碼實(shí)現(xiàn),要看的只有一個(gè)Observable類和一個(gè)Observer接口。

JDK標(biāo)準(zhǔn)類實(shí)現(xiàn)觀察者模式

import java.util.Observable;

import java.util.Observer;

/**

* 使用java.util包中的標(biāo)準(zhǔn)類實(shí)現(xiàn)觀察者模式

* @author will

*

*/

public class JDKObserverDemo {

public static void main(String[] args) {

JDKObserverDemo jod = new JDKObserverDemo();

// 被觀察者

MyObservable myObservable = jod.new MyObservable("hello");

// 觀察者

Observer myObserver = jod.new MyObserver();

// 注冊(cè)

myObservable.addObserver(myObserver);

// 改變被觀察者狀態(tài),觸發(fā)觀察者回調(diào)函數(shù)

myObservable.setValue("will");

}

class MyObservable extends Observable {

private String watchedValue;?? // 被觀察的值

public MyObservable(String watchedValue) {

this.watchedValue = watchedValue;

}

public void setValue(String newValue) {

if(!watchedValue.equals(newValue)) {

watchedValue = newValue;

setChanged();

notifyObservers(newValue);

}

}

@Override

public String toString() {

return "MyObservable";

}

}

class MyObserver implements Observer {

@Override

public void update(Observable o, Object arg) {

System.out.println(o + "'s state changed, argument is: " + arg);

}

}

}

看了下JDK標(biāo)準(zhǔn)庫中的Observer和Observable實(shí)現(xiàn)很簡(jiǎn)單,不想多說了。

下面是Quartz中的監(jiān)聽器實(shí)現(xiàn)。

QuartzScheduler被監(jiān)聽者

import java.util.ArrayList;

import java.util.Date;

import java.util.List;

/**

* Quartz核心類,相當(dāng)于Observable(被觀察者)

* @author will

*

*/

public class QuartzScheduler {

private ArrayList internalSchedulerListeners = new ArrayList(10);

//?private ArrayList interanlJobListeners = new ArrayList();?? // 一個(gè)Observable可以包含多組監(jiān)聽器

public Date scheduleJob(Trigger trigger) {

if(trigger == null) {

return null;

}

System.out.println("Schedule job, trigger: " + trigger);

notifySchedulerListenersScheduled(trigger);

return new Date();

}

public void unScheduleJob(Trigger trigger) {

if(trigger == null) {

return;

}

System.out.println("Unschedule job, trigger: " + trigger);

notifyShedulerListenerUnScheduled(trigger);

}

// 注冊(cè)SchedulerListener

public void addInternalSchedulerListener(SchedulerListener schedulerListener) {

synchronized (internalSchedulerListeners) {

internalSchedulerListeners.add(schedulerListener);

}

}

// 移除SchedulerListener

public boolean removeInternalSchedulerListener(SchedulerListener schedulerListener) {

synchronized (internalSchedulerListeners) {

return internalSchedulerListeners.remove(schedulerListener);

}

}

public List getInternalSchedulerListeners() {

synchronized (internalSchedulerListeners) {

return java.util.Collections.unmodifiableList(new ArrayList(internalSchedulerListeners));

}

}

public void notifySchedulerListenersScheduled(Trigger trigger) {

for(SchedulerListener listener: getInternalSchedulerListeners()) {

listener.jobScheduled(trigger);

}

}

public void notifyShedulerListenerUnScheduled(Trigger trigger) {

for(SchedulerListener listener: getInternalSchedulerListeners()) {

listener.jobUnScheduled(trigger);

}

}

}

SchedulerListener

// 監(jiān)聽接口,回調(diào)函數(shù),Client注冊(cè)監(jiān)聽時(shí)需要提供回調(diào)函數(shù)實(shí)現(xiàn)

public interface SchedulerListener {

void jobScheduled(Trigger trigger);

void jobUnScheduled(Trigger trigger);

}

Trigger

// Trigger

public class Trigger {

private String triggerKey;

private String triggerName;

public Trigger(String triggerKey, String triggerName) {

this.triggerKey = triggerKey;

this.triggerName = triggerName;

}

public String getTriggerKey() {

return triggerKey;

}

public void setTriggerKey(String triggerKey) {

this.triggerKey = triggerKey;

}

public String getTriggerName() {

return triggerName;

}

public void setTriggerName(String triggerName) {

this.triggerName = triggerName;

}

public String toString() {

return String.format("{triggerKey: %s, triggerName: %s}", triggerKey, triggerName);

}

}

Test

public class Test {

public static void main(String[] args) {

QuartzScheduler qs = new QuartzScheduler();

SchedulerListener listenerA = new SchedulerListener() {

@Override

public void jobUnScheduled(Trigger trigger) {

System.out.println("listenerA job unscheduled: " + trigger.getTriggerName());

}

@Override

public void jobScheduled(Trigger trigger) {

System.out.println("listenerA job scheduled: " + trigger.getTriggerName());

}

};

SchedulerListener listenerB = new SchedulerListener() {

@Override

public void jobUnScheduled(Trigger trigger) {

System.out.println("listenerB job unscheduled: " + trigger.getTriggerName());

}

@Override

public void jobScheduled(Trigger trigger) {

System.out.println("listenerB job scheduled: " + trigger.getTriggerName());

}

};

// 注冊(cè)Scheduler Listener

qs.addInternalSchedulerListener(listenerA);

qs.addInternalSchedulerListener(listenerB);

Trigger triggerA = new Trigger("Key1", "triggerA");

Trigger triggerB = new Trigger("Key2", "triggerB");

qs.scheduleJob(triggerA);

qs.scheduleJob(triggerB);

qs.unScheduleJob(triggerA);

}

}

總結(jié)

以上是生活随笔為你收集整理的java jdk 观察者模式_java观察者模式实现和java观察者模式演化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。