Observer观察者设计模式
目錄
問題
程序模擬?
版本一:while死循環(huán)
版本二:面向?qū)ο笫降厣档?
版本三:加入觀察者
版本四:加入多個觀察者
版本五:分離觀察者與被觀察者
版本六:觀察者根據(jù)事件來作出處理
版本七:處理事件需要事件源對象
版本八:事件形成繼承體系
java.awt.Frame類應用觀察者模式
?
reactor模型的本質(zhì)就是觀察者模式。
問題
首先來看一個問題:
程序模擬?
版本一:while死循環(huán)
程序模擬小孩哭:一個死循環(huán)等著,當cry為true時就執(zhí)行。類似于面向過程式地傻等
/*** 披著面向?qū)ο笸庖碌拿嫦蜻^程*/public class Main1 {public static void main(String[] args) {boolean cry = false;while(!cry) {//進行處理}} }版本二:面向?qū)ο笫降厣档?
抽象出一個Child類來,提供一個wakeUp()方法和一個cry屬性。本質(zhì)上同版本一沒區(qū)別,只不過用了面向?qū)ο蟮乃枷搿?/p> /*** 面向?qū)ο蟮纳档?/class Child {private boolean cry = false;public boolean isCry() {return cry;}public void wakeUp() {System.out.println("Waked Up! Crying wuwuwuwu...");cry = true;} }public class Main {public static void main(String[] args) {Child child = new Child();while(!child.isCry()) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("observing...");}} }
版本三:加入觀察者
加入觀察者Dad。當Child的wakeUp()了之后就調(diào)用Dad的feed()方法
/*** 加入觀察者*/class Child {private boolean cry = false;private Dad d = new Dad();public boolean isCry() {return cry;}public void wakeUp() {cry = true;d.feed();} }class Dad {public void feed() {System.out.println("dad feeding...");} }public class Main {public static void main(String[] args) {Child c = new Child();//do sthc.wakeUp();} }版本四:加入多個觀察者
/*** 加入多個觀察者*/class Child {private boolean cry = false;private Dad dad = new Dad();private Mum mum = new Mum();private Dog dog = new Dog();public boolean isCry() {return cry;}public void wakeUp() {cry = true;dad.feed();dog.wang();mum.hug();} }class Dad {public void feed() {System.out.println("dad feeding...");} }class Mum {public void hug() {System.out.println("mum hugging...");} }class Dog {public void wang() {System.out.println("dog wang...");} }public class Main {public static void main(String[] args) {Child c = new Child();//do sthc.wakeUp();} }版本五:分離觀察者與被觀察者
定義一個觀察者接口Observer,提供一個actionOnWakeUp()方法供觀察者實現(xiàn)。
/*** 分離觀察者與被觀察者*/class Child {private boolean cry = false;private List<Observer> observers = new ArrayList<>();{observers.add(new Dad());observers.add(new Mum());observers.add(new Dog());}public boolean isCry() {return cry;}public void wakeUp() {cry = true;for(Observer o : observers) {o.actionOnWakeUp();}} }interface Observer {void actionOnWakeUp(); }class Dad implements Observer {public void feed() {System.out.println("dad feeding...");}@Overridepublic void actionOnWakeUp() {feed();} }class Mum implements Observer {public void hug() {System.out.println("mum hugging...");}@Overridepublic void actionOnWakeUp() {hug();} }class Dog implements Observer {public void wang() {System.out.println("dog wang...");}@Overridepublic void actionOnWakeUp() {wang();} }public class Main {public static void main(String[] args) {Child c = new Child();//do sthc.wakeUp();} }版本六:觀察者根據(jù)事件來作出處理
有很多時候,觀察者需要根據(jù)事件的具體情況來進行處理。
①Source--事件源對象
②Observer--觀察者(監(jiān)聽者)
③Event--事件對象
事件源對象Source會發(fā)出一些事件Event,Observer觀察者觀察到這些事件后作出一系列的反應。
比如鍵盤監(jiān)聽對象MyKeyListener extends KeyAdapter,事件源對象就是窗口Frame,事件對象是KeyEvent,觀察者(監(jiān)聽器)是MykeyListener。
import java.util.ArrayList; import java.util.List;/*** 有很多時候,觀察者需要根據(jù)事件的具體情況來進行處理*/class Child {private boolean cry = false;private List<Observer> observers = new ArrayList<>();{observers.add(new Dad());observers.add(new Mum());observers.add(new Dog());}public boolean isCry() {return cry;}public void wakeUp() {cry = true;wakeUpEvent event = new wakeUpEvent(System.currentTimeMillis(), "bed");for(Observer o : observers) {o.actionOnWakeUp(event);}} }//事件類 fire Event class wakeUpEvent{long timestamp;String loc;public wakeUpEvent(long timestamp, String loc) {this.timestamp = timestamp;this.loc = loc;} }interface Observer {void actionOnWakeUp(wakeUpEvent event); }class Dad implements Observer {public void feed() {System.out.println("dad feeding...");}@Overridepublic void actionOnWakeUp(wakeUpEvent event) {feed();} }class Mum implements Observer {public void hug() {System.out.println("mum hugging...");}@Overridepublic void actionOnWakeUp(wakeUpEvent event) {hug();} }class Dog implements Observer {public void wang() {System.out.println("dog wang...");}@Overridepublic void actionOnWakeUp(wakeUpEvent event) {wang();} }public class Main {public static void main(String[] args) {Child c = new Child();//do sthc.wakeUp();} }版本七:處理事件需要事件源對象
?* 有很多時候,觀察者需要根據(jù)事件的具體情況來進行處理
?* 大多數(shù)時候,我們處理事件的時候,需要事件源對象
版本八:事件形成繼承體系
?* 有很多時候,觀察者需要根據(jù)事件的具體情況來進行處理
?* 大多數(shù)時候,我們處理事件的時候,需要事件源對象
?* 事件也可以形成繼承體系
java.awt.Frame類應用觀察者模式
import java.awt.Button; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent;public class TestFrame extends Frame {public void launch() {Button b = new Button("press me");b.addActionListener(new MyActionListener());b.addActionListener(new MyActionListener2());this.add(b);this.pack();this.addWindowListener(new WindowAdapter(){@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});this.setLocation(400, 400);this.setVisible(true);}public static void main(String[] args) {new TestFrame().launch();}private class MyActionListener implements ActionListener { //Observerpublic void actionPerformed(ActionEvent e) {((Button)e.getSource()).setLabel("press me again!");System.out.println("button pressed!");}}private class MyActionListener2 implements ActionListener {public void actionPerformed(ActionEvent e) {System.out.println("button pressed 2!");}} }?
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Observer观察者设计模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx面试中最常见的18道题及答案
- 下一篇: Builder建造者设计模式