Observer观察者设计模式
目錄
問題
程序模擬?
版本一:while死循環
版本二:面向對象式地傻等?
版本三:加入觀察者
版本四:加入多個觀察者
版本五:分離觀察者與被觀察者
版本六:觀察者根據事件來作出處理
版本七:處理事件需要事件源對象
版本八:事件形成繼承體系
java.awt.Frame類應用觀察者模式
?
reactor模型的本質就是觀察者模式。
問題
首先來看一個問題:
程序模擬?
版本一:while死循環
程序模擬小孩哭:一個死循環等著,當cry為true時就執行。類似于面向過程式地傻等
/*** 披著面向對象外衣的面向過程*/public class Main1 {public static void main(String[] args) {boolean cry = false;while(!cry) {//進行處理}} }版本二:面向對象式地傻等?
抽象出一個Child類來,提供一個wakeUp()方法和一個cry屬性。本質上同版本一沒區別,只不過用了面向對象的思想。
/*** 面向對象的傻等*/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()了之后就調用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()方法供觀察者實現。
/*** 分離觀察者與被觀察者*/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();} }版本六:觀察者根據事件來作出處理
有很多時候,觀察者需要根據事件的具體情況來進行處理。
①Source--事件源對象
②Observer--觀察者(監聽者)
③Event--事件對象
事件源對象Source會發出一些事件Event,Observer觀察者觀察到這些事件后作出一系列的反應。
比如鍵盤監聽對象MyKeyListener extends KeyAdapter,事件源對象就是窗口Frame,事件對象是KeyEvent,觀察者(監聽器)是MykeyListener。
import java.util.ArrayList; import java.util.List;/*** 有很多時候,觀察者需要根據事件的具體情況來進行處理*/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();} }版本七:處理事件需要事件源對象
?* 有很多時候,觀察者需要根據事件的具體情況來進行處理
?* 大多數時候,我們處理事件的時候,需要事件源對象
版本八:事件形成繼承體系
?* 有很多時候,觀察者需要根據事件的具體情況來進行處理
?* 大多數時候,我們處理事件的時候,需要事件源對象
?* 事件也可以形成繼承體系
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位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Observer观察者设计模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx面试中最常见的18道题及答案
- 下一篇: lambda中的钩子函数