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

news2024/11/18 11:30:38

简要说明

事件处理模型

场景示例:小朋友睡醒了哭,饿!

一、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类,模拟按钮点击事件

  • 自定义监听者 MyActionEventListenerMyActionEventListener2实现接口 void actionPerformed(ActionEvent e);

  • main主方法程序Button添加监听者MyActionEventListenerMyActionEventListener2, 模拟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-Patternsicon-default.png?t=N7T8https://github.com/jxaufang168/Design-Patterns


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1390121.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 从零开始:05 MySQL 数据类型

文章目录 1、数值类型1.1 整形数值1.2 浮点型数值1.3 布尔值 2、日期和时间类型3、字符串类型3.1 CHAR 和 VARCHAR3.2 BINARY 和 VARBINARY3.3 BLOB 和 TEXT3.4 ENUM 类型3.5 SET 类型 4、空间数据类型5、JSON 数据类型5、JSON 数据类型 前面的讲解中已经接触到了表的创建&…

这款软件轻松解决你图片水印问题

随着数字时代的到来&#xff0c;图片已经成为我们生活中不可或缺的一部分。然而&#xff0c;很多时候&#xff0c;我们会遇到带有水印的图片&#xff0c;这不仅影响了图片的视觉效果&#xff0c;还可能遮挡了重要的内容。这时&#xff0c;一款专业的去水印工具就显得尤为重要。…

博途PLC增量式PID和脉冲轴组合控制阀门开度(算法介绍)

这篇博客我们以S7-1200PLC平台来举例,介绍我们的PID闭环控制器如何控制脉冲轴实现阀门角度控制。SMART PLC PID控制器控制伺服驱动器实现关节角度控制详细内容请参考下面文章: https://rxxw-control.blog.csdn.net/article/details/129658364https://rxxw-control.blog.csdn…

Python基础语法(中)—— python列表、字符串、函数

文章目录 5. python中的列表5.1 列表的初始化5.1.1 直接初始化5.1.2 通过append函数初始化5.1.3 通过for语句初始化列表长度和每个位置的数值 5.2访问列表元素5.3使用循环语句遍历列表5.4列表的切片操作5.5列表的复制5.6列表的运算5.7列表的常用操作5.8嵌套列表5.9列表其他小知…

【手撕C语言 第二集】初识C语言

​​ 一、变量的作用域和生命周期 作用域&#xff1a;一个变量在哪里可以使用它&#xff0c;哪里就是它的作用域。 局部变量的作用域&#xff1a;变量所在的局部范围 全局变量的作用域&#xff1a;整个工程 不管整个工程里面有多少源文件&#xff0c;都可以使用全局变量。这样…

力扣电话号码的组合

文章目录 题目说明做题思路代码实现代码解析 题目链接 题目说明 首先我们先分析一下这个题目题目中说呢先给出一个字符串这个字符串其实就是这个九键数字我们要按照要求将数字所代表的字符进行自由组合形成一个字符串并且这个字符串的长度和输入的数字字符串长度相同&#xff0…

《每天一分钟学习C语言·十二》各种指针问题

1、 int arr; int * restrict pt &arr; *pt 100; *arr 10;注&#xff1a;restrict只能修饰指针&#xff0c;被restrict修饰的指针指向一块内存后这块内存就归这个指针管理了&#xff0c;其他任何指针都不能修改这块内存的内容&#xff0c;这是一个约定&#xff0c;当…

备份和容灾讲解

备份和容灾 &#xff08;1&#xff09;容灾&#xff08;容许灾难的发生&#xff09;是一种架构方案&#xff0c;包括了很多方案&#xff0c;如下 本地高可用 双活&#xff08;特指存储&#xff0c;可以理解为两端同时对外提供服务&#xff09;&#xff1a;通过一个双写模块把…

20240115-插入删除 GetRandom O(1)

题目要求 实现 RandomizedSet 类&#xff1a; RandomizedSet() 初始化 RandomizedSet 对象。bool insert(int val) 将不存在的项目 val 插入随机集合。如果项目不存在&#xff0c;则返回 true&#xff0c;否则返回 false。bool remove(int val) 从集合中删除项目 val&#xf…

文理导航期刊投稿方式

《文理导航》杂志系国家新闻出版总署批准&#xff0c;内蒙古自治区文旅厅主管&#xff0c;内蒙古自治区北方文化研究院主办的&#xff0c;面向大中专院校、中小学教育的专业性教育刊物&#xff0c;阅读对象是关心教育事业发展的大中专院校、职业教育、中小学教育的专家、教研员…

FFmpeg连载6-音频重采样

今天我们的实战内容是将音频解码成PCM&#xff0c;并将PCM重采样成特定的采样率&#xff0c;然后输出到本地文件进行播放。 什么是重采样&#xff1f; 所谓重采样&#xff0c;一句话总结就是改变音频的三元素&#xff0c;也就是通过重采样改变音频的采样率、采样格式或者声道数…

PHP项目添加分布式锁,这里是ThinkPHP8框架实现分布式锁

背景&#xff1a;公司旧项目&#xff0c;最初访问量不多&#xff0c;单机部署的。后来&#xff0c;访问量上来了&#xff0c;有阵子很卡&#xff0c;公司决定横向扩展&#xff0c;后端代码部署了三台服务器。部署调整后&#xff0c;有用户反馈&#xff0c;一个订单支付了三次。…

【机器学习入门】机器学习基础概念与原理

*&#xff08;本篇文章旨在帮助新手了解机器学习的基础概念和原理&#xff0c;不深入讨论算法及核心公式&#xff09; 目录 一、机器学习概念 1、什么是机器学习&#xff1f; 2、常见机器学习算法和模型 3、使用Python编程语言进行机器学习实践 4、机器学习的应用领域 二…

从零学Java 多线程的三个特性

多线程的三个特性 多线程要保证并发线程正确执行&#xff0c;必须要保证三个特性。 1 原子性&#xff08;互斥性&#xff09;&#xff1a; 一个或多个操作不能被分割&#xff0c;要么全部执行&#xff0c;要么就都不执行。 2 可见性&#xff1a; 多个线程访问同一个变量&a…

续航50年原子能电池揭秘

我国公司Betavolt最近宣布推出一款面向消费者市场的原子能电池&#xff0c;声称其使用寿命长达50年。首款采用该公司新型原子电池技术的产品名为Betavolt BV100&#xff0c;主要构造材料包括镍-63同位素和金刚石半导体材料。Betavolt表示&#xff0c;其核电池将主要应用于航空航…

【Linux技术专题】「夯实基本功系列」带你一同学习和实践操作Linux服务器必学的Shell指令(排查问题指令 - 下)

带你一同学习和实践操作Linux服务器必学的Shell指令 前提介绍more和less命令用法more命令命令格式命令参数 常用操作命令案例分析显示文件中从第3行起的内容将日志内容设置为每屏显示4行快速定位和显示文件中包含特定字符串结合管道和more命令来分页显示 less指令命令格式搜索指…

【C++进阶】心心念念的红黑树,它来了!

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

codesys【看门狗】

看门狗&#xff1a; 时间&#xff1a; 看门狗饿死时间。灵敏度&#xff1a;是看门狗时间的倍数。看门狗1秒&#xff0c;灵敏度5&#xff0c;结果就是5秒。Task类型&#xff1a; 循环&#xff1a;用于现场总线。惯性滑行&#xff1a;CPU空闲就运行&#xff0c;主程序用这个。 P…

【模板规范】会议纪要模板

文章目录 1、简介2、纪要模板2.1、表格类会议纪要2.2、文档类会议纪要2.3、简易版项目纪要 3、会议纪要3.1、作用3.2、特点3.2.1、工作会议纪要3.2.2、代表会议纪要3.2.3、座谈会议纪要3.2.4、联席会议纪要3.2.5、办公会议纪要3.2.6、汇报会议纪要3.2.7、技术鉴定会议纪要 3.3、…

HCS私有云简介

1、HCS简介和发展史 华为云产品&#xff1a;私有云和公有云&#xff0c;现在的私有云已经和公有云越来越像了FusionSphere是华为的一个品牌2016年&#xff0c;在5.0版本的时候&#xff0c;华为Openstack叫FusionSphere Openstack 5.0&#xff0c;底层用的是suse操作系统&#…