目录
问题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 sth
c.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 sth
c.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...");
}
@Override
public void actionOnWakeUp() {
feed();
}
}
class Mum implements Observer {
public void hug() {
System.out.println("mum hugging...");
}
@Override
public void actionOnWakeUp() {
hug();
}
}
class Dog implements Observer {
public void wang() {
System.out.println("dog wang...");
}
@Override
public void actionOnWakeUp() {
wang();
}
}
public class Main {
public static void main(String[] args) {
Child c = new Child();
//do sth
c.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...");
}
@Override
public void actionOnWakeUp(wakeUpEvent event) {
feed();
}
}
class Mum implements Observer {
public void hug() {
System.out.println("mum hugging...");
}
@Override
public void actionOnWakeUp(wakeUpEvent event) {
hug();
}
}
class Dog implements Observer {
public void wang() {
System.out.println("dog wang...");
}
@Override
public void actionOnWakeUp(wakeUpEvent event) {
wang();
}
}
public class Main {
public static void main(String[] args) {
Child c = new Child();
//do sth
c.wakeUp();
}
}
版本七:处理事件需要事件源对象
* 有很多时候,观察者需要根据事件的具体情况来进行处理
* 大多数时候,我们处理事件的时候,需要事件源对象
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", this);
for(Observer o : observers) {
o.actionOnWakeUp(event);
}
}
}
class wakeUpEvent{
long timestamp;
String loc;
Child source;
public wakeUpEvent(long timestamp, String loc, Child source) {
this.timestamp = timestamp;
this.loc = loc;
this.source = source;
}
}
interface Observer {
void actionOnWakeUp(wakeUpEvent event);
}
class Dad implements Observer {
public void feed() {
System.out.println("dad feeding...");
}
@Override
public void actionOnWakeUp(wakeUpEvent event) {
feed();
}
}
class Mum implements Observer {
public void hug() {
System.out.println("mum hugging...");
}
@Override
public void actionOnWakeUp(wakeUpEvent event) {
hug();
}
}
class Dog implements Observer {
public void wang() {
System.out.println("dog wang...");
}
@Override
public void actionOnWakeUp(wakeUpEvent event) {
wang();
}
}
public class Main {
public static void main(String[] args) {
Child c = new Child();
//do sth
c.wakeUp();
}
}
版本八:事件形成继承体系
* 有很多时候,观察者需要根据事件的具体情况来进行处理
* 大多数时候,我们处理事件的时候,需要事件源对象
* 事件也可以形成继承体系
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", this);
for(Observer o : observers) {
o.actionOnWakeUp(event);
}
}
}
abstract class Event<T> {
abstract T getSource();
}
class wakeUpEvent extends Event<Child>{
long timestamp;
String loc;
Child source;
public wakeUpEvent(long timestamp, String loc, Child source) {
this.timestamp = timestamp;
this.loc = loc;
this.source = source;
}
@Override
Child getSource() {
return source;
}
}
interface Observer {
void actionOnWakeUp(wakeUpEvent event);
}
class Dad implements Observer {
public void feed() {
System.out.println("dad feeding...");
}
@Override
public void actionOnWakeUp(wakeUpEvent event) {
feed();
}
}
class Mum implements Observer {
public void hug() {
System.out.println("mum hugging...");
}
@Override
public void actionOnWakeUp(wakeUpEvent event) {
hug();
}
}
class Dog implements Observer {
public void wang() {
System.out.println("dog wang...");
}
@Override
public void actionOnWakeUp(wakeUpEvent event) {
wang();
}
}
public class Main {
public static void main(String[] args) {
Child c = new Child();
//do sth
c.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(){
@Override
public 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 { //Observer
public 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!");
}
}
}