【设计模式-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

相关推荐
冰帝海岸40 分钟前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象1 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了2 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
小二·2 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic2 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
懒洋洋大魔王2 小时前
RocketMQ的使⽤
java·rocketmq·java-rocketmq
武子康2 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
转世成为计算机大神3 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
qq_327342733 小时前
Java实现离线身份证号码OCR识别
java·开发语言
小乖兽技术4 小时前
23种设计模式速记法
设计模式