【设计模式-06】Observer观察者模式

简要说明

事件处理模型
场景示例:小朋友睡醒了哭,饿!

一、v1版本(披着面向对象的外衣的面向过程)

/**
 * @description: 观察者模式-v1版本(披着面向对象的外衣的面向过程)
 * @author: flygo
 * @time: 2022/7/18 16:57
 */
public class ObserverMain {

  public static void main(String[] args) {
    boolean cry = false;

    if (!cry) {
      // 进行处理
    }
  }
}

二、v2版本(面向对象的傻等)

/**
 * @description: 观察者模式-v2版本(面向对象的傻等)
 * @author: flygo
 * @time: 2022/7/18 16:57
 */
public class ObserverMain {

  public static void main(String[] args) {
    Child child = new Child();

    while (!child.isCry()) {
      try {
        Thread.sleep(10000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("Observing......");
    }
  }
}

class Child {
  private boolean cry = false;

  public boolean isCry() {
    return cry;
  }

  public void setCry(boolean cry) {
    this.cry = cry;
  }

  public void wakeUp() {
    System.out.println("Waked Up!Crying.......");
  }
}

三、v3版本(加入观察者)

/**
 * @description: 观察者模式-v3版本(加入观察者)
 * @author: flygo
 * @time: 2022/7/18 16:57
 */
public class ObserverMain {

  public static void main(String[] args) {
    Child child = new Child();
    child.wakeUp();
  }
}

class Dad {
  public void feed() {
    System.out.println("Dad feeding...");
  }
}

class Child {
  private boolean cry = false;
  private Dad dad = new Dad();

  public boolean isCry() {
    return cry;
  }

  public void setCry(boolean cry) {
    this.cry = cry;
  }

  public void wakeUp() {
    cry = true;
    dad.feed();
  }
}

四、v4版本(加入多个观察者)

/**
 * @description: 观察者模式-v4版本(加入多个观察者)
 * @author: flygo
 * @time: 2022/7/18 16:57
 */
public class ObserverMain {

  public static void main(String[] args) {
    Child child = new Child();
    child.wakeUp();
  }
}

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...");
  }
}

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 setCry(boolean cry) {
    this.cry = cry;
  }

  public void wakeUp() {
    cry = true;
    dad.feed();
    mum.hug();
    dog.wang();
  }
}

五、v5版本(加入多个观察者,采用接口的实现方式)

/**
 * @description: 观察者模式-v5版本(加入多个观察者,采用接口实现的方式)
 * @author: flygo
 * @time: 2022/7/18 16:57
 */
public class ObserverMain {

  public static void main(String[] args) {
    Child child = new Child();
    child.wakeUp();
  }
}

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();
  }
}

class Child {
  private boolean cry = false;

  private List<Observer> observerList = new ArrayList<>();

  {
    observerList.add(new Dad());
    observerList.add(new Mum());
    observerList.add(new Dog());
  }

  public boolean isCry() {
    return cry;
  }

  public void setCry(boolean cry) {
    this.cry = cry;
  }

  public void wakeUp() {
    cry = true;
    for (Observer o : observerList) {
      o.actionOnWakeUp();
    }
  }
}

六、v6版本(加入多个观察者,增加事件对象)

import java.util.ArrayList;
import java.util.List;

/**
 * @description: 观察者模式-v5版本(加入多个观察者,增加事件对象)
 * @author: flygo
 * @time: 2022/7/18 16:57
 */
public class ObserverMain {

  public static void main(String[] args) {
    Child child = new Child();
    child.wakeUp();
  }
}

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();
  }
}

class Child {
  private boolean cry = false;

  private List<Observer> observerList = new ArrayList<>();

  {
    observerList.add(new Dad());
    observerList.add(new Mum());
    observerList.add(new Dog());
  }

  public boolean isCry() {
    return cry;
  }

  public void setCry(boolean cry) {
    this.cry = cry;
  }

  public void wakeUp() {
    cry = true;

    WakeUpEvent event = new WakeUpEvent(System.currentTimeMillis(), "bed");

    for (Observer o : observerList) {
      o.actionOnWakeUp(event);
    }
  }
}

七、v7版本(加入多个观察者,增加事件对象且时间对象增加事件源)

import java.util.ArrayList;
import java.util.List;

/**
 * @description: 观察者模式-v5版本(加入多个观察者,增加事件对象且事件对象增加事件源)
 * @author: flygo
 * @time: 2022/7/18 16:57
 */
public class ObserverMain {

  public static void main(String[] args) {
    Child child = new Child();
    child.wakeUp();
  }
}

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();
  }
}

class WakeUpEvent {
  long timestamp;
  String loc;
  Child child;

  public WakeUpEvent(long timestamp, String loc, Child child) {
    this.timestamp = timestamp;
    this.loc = loc;
    this.child = child;
  }
}

class Child {
  private boolean cry = false;
  private List<Observer> observerList = new ArrayList<>();

  {
    observerList.add(new Dad());
    observerList.add(new Mum());
    observerList.add(new Dog());
  }

  public boolean isCry() {
    return cry;
  }

  public void setCry(boolean cry) {
    this.cry = cry;
  }

  public void wakeUp() {
    cry = true;
    WakeUpEvent event = new WakeUpEvent(System.currentTimeMillis(), "bed", this);
    for (Observer o : observerList) {
      o.actionOnWakeUp(event);
    }
  }
}

八、v8版本(加入多个观察者,事件体系)

import java.util.ArrayList;
import java.util.List;

/**
 * @description: 观察者模式-v5版本(加入多个观察者,事件体系)
 * @author: flygo
 * @time: 2022/7/18 16:57
 */
public class ObserverMain {

  public static void main(String[] args) {
    Child child = new Child();
    child.wakeUp();
  }
}

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();
  }
}

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;
  }
}

class Child {
  private boolean cry = false;
  private List<Observer> observerList = new ArrayList<>();

  {
    observerList.add(new Dad());
    observerList.add(new Mum());
    observerList.add(new Dog());
  }

  public boolean isCry() {
    return cry;
  }

  public void setCry(boolean cry) {
    this.cry = cry;
  }

  public void wakeUp() {
    cry = true;
    WakeUpEvent event = new WakeUpEvent(System.currentTimeMillis(), "bed", this);
    for (Observer o : observerList) {
      o.actionOnWakeUp(event);
    }
  }
}

九、v9版本(java原生awt button使用的观察模式和模拟原生awt Button实现观察者模式)

1、java原生awt button使用的观察模式

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/**
 * @description: 简单的一个按钮点击小例子演示java原生使用的观察者模式
 * @author: flygo
 * @time: 2022/7/19 10:20
 */
public class TestFrame extends Frame {

  public void launch() {
    Button button = new Button("press me");
    button.addActionListener(new MyButtonActionListener());
    button.addActionListener(new MyButtonActionListener2());

    this.add(button);
    this.pack();

    this.addWindowListener(
        new WindowAdapter() {
          @Override
          public void windowClosing(WindowEvent e) {
            super.windowClosing(e);
            System.exit(0);
          }
        });
    this.setLocation(400, 400);
    this.setVisible(true);
  }

  public static void main(String[] args) {
    new TestFrame().launch();
  }
}

class MyButtonActionListener implements ActionListener {
  @Override
  public void actionPerformed(ActionEvent e) {
    ((Button) e.getSource()).setLabel("press me again!");
    System.out.println("button pressed!");
  }
}

class MyButtonActionListener2 implements ActionListener {
  @Override
  public void actionPerformed(ActionEvent e) {
    System.out.println("button pressed again!");
  }
}

2、模拟原生awt Button实现观察者模式

核心思路和逻辑

  • 定义事件类 ActionEvent
  • 定义接口类 ActionListener****和接口方法 void actionPerformed(ActionEvent e);
  • 自定义 Button****类,模拟按钮点击事件
  • 自定义监听者 MyActionEventListener****和 MyActionEventListener2****实现接口 void actionPerformed(ActionEvent e);
  • main主方法程序 Button****添加监听者 MyActionEventListener****和 MyActionEventListener2**, 模拟** Button****调用点击方法 buttonPressed
import java.util.ArrayList;
import java.util.List;

/**
 * @description: 模拟Java原生awt button观察者模式
 * @author: flygo
 * @time: 2022/7/19 11:09
 */
public class ButtonObserverMain {

  public static void main(String[] args) {
    Button button = new Button();
    button.addActionListener(new MyActionEventListener());
    button.addActionListener(new MyActionEventListener2());

    button.buttonPressed();
  }
}

interface ActionListener {
  void actionPerformed(ActionEvent e);
}

class ActionEvent {
  long when;
  Object source;

  public ActionEvent(long when, Object source) {
    this.when = when;
    this.source = source;
  }

  public long getWhen() {
    return when;
  }

  public Object getSource() {
    return source;
  }
}

class Button {
  private List<ActionListener> listenerList = new ArrayList<>();

  public void buttonPressed() {
    ActionEvent event = new ActionEvent(System.currentTimeMillis(), this);
    for (ActionListener listener : listenerList) {
      listener.actionPerformed(event);
    }
  }

  public void addActionListener(ActionListener listener) {
    this.listenerList.add(listener);
  }
}

class MyActionEventListener implements ActionListener {

  @Override
  public void actionPerformed(ActionEvent e) {
    System.out.println("button pressed!");
  }
}

class MyActionEventListener2 implements ActionListener {

  @Override
  public void actionPerformed(ActionEvent e) {
    System.out.println("button pressed again!");
  }
}

十、v10版本(使用Lambda表达式实现回调或钩子函数)

JavaScript 中有钩子函数,其实就是观察者模式

import java.util.ArrayList;
import java.util.List;

/**
 * @description: 模拟Java原生awt button观察者模式-钩子函数(hook)、回调(callback)、observer
 * @author: flygo
 * @time: 2022/7/19 11:09
 */
public class ButtonObserverMain {

  public static void main(String[] args) {
    Button button = new Button();
    button.addActionListener(new MyActionEventListener());
    button.addActionListener(new MyActionEventListener2());

    button.addActionListener(
        (e) -> {
          System.out.println("This is lambda listener!");
        });

    button.buttonPressed();
  }
}

interface ActionListener {
  void actionPerformed(ActionEvent e);
}

class ActionEvent {
  long when;
  Object source;

  public ActionEvent(long when, Object source) {
    this.when = when;
    this.source = source;
  }

  public long getWhen() {
    return when;
  }

  public Object getSource() {
    return source;
  }
}

class Button {
  private List<ActionListener> listenerList = new ArrayList<>();

  public void buttonPressed() {
    ActionEvent event = new ActionEvent(System.currentTimeMillis(), this);
    for (ActionListener listener : listenerList) {
      listener.actionPerformed(event);
    }
  }

  public void addActionListener(ActionListener listener) {
    this.listenerList.add(listener);
  }
}

class MyActionEventListener implements ActionListener {

  @Override
  public void actionPerformed(ActionEvent e) {
    System.out.println("button pressed!");
  }
}

class MyActionEventListener2 implements ActionListener {

  @Override
  public void actionPerformed(ActionEvent e) {
    System.out.println("button pressed again!");
  }
}

十一、JavaScript中的event事件

在很多系统中,Observer模式往往和责任链共同负责对于事件的处理,其中的某一个observer负责是否将事件往下传

<script type="text/javascript">
  function handle() {
    alert(event.target.value);
  }
</script>

<input type="button" value="press me" name="button" onclick="handle()" />

十二、源码地址

https://github.com/jxaufang168/Design-Patternshttps://github.com/jxaufang168/Design-Patterns

相关推荐
李小白667 分钟前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp19 分钟前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea
装不满的克莱因瓶1 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb
n北斗1 小时前
常用类晨考day15
java
骇客野人1 小时前
【JAVA】JAVA接口公共返回体ResponseData封装
java·开发语言
yuanbenshidiaos2 小时前
c++---------数据类型
java·jvm·c++
向宇it2 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
Lojarro2 小时前
【Spring】Spring框架之-AOP
java·mysql·spring
莫名其妙小饼干2 小时前
网上球鞋竞拍系统|Java|SSM|VUE| 前后端分离
java·开发语言·maven·mssql
isolusion3 小时前
Springboot的创建方式
java·spring boot·后端