【设计模式-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...");}@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();}
}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...");}@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();}
}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...");}@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();}
}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...");}@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();}
}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;}@OverrideChild 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() {@Overridepublic 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 {@Overridepublic void actionPerformed(ActionEvent e) {((Button) e.getSource()).setLabel("press me again!");System.out.println("button pressed!");}
}class MyButtonActionListener2 implements ActionListener {@Overridepublic 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 {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("button pressed!");}
}class MyActionEventListener2 implements ActionListener {@Overridepublic 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 {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("button pressed!");}
}class MyActionEventListener2 implements ActionListener {@Overridepublic 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.hqwc.cn/news/417623.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

thinkadmin表单上传单图,多图,单文件,多文件

{extend name="../../admin/view/main"}{block name=content} <form action="{:sysuri()}" class="layui-card layui-form" data-auto="tr

安装pycharm

1.浏览器打开链接 PyCharm: the Python IDE for Professional Developers by JetBrains 2.开始下载 3.下载windows版本的软件 4.双击运行软件&#xff0c;点击下一步 5.安装路径默认不进行修改 6.选项全部勾选&#xff0c;点击下一步 7.开始安装 8.选择稍后重启 9.桌面生成图标…

三国游戏(寒假每日一题+贪心、枚举)

题目 小蓝正在玩一款游戏。 游戏中魏蜀吴三个国家各自拥有一定数量的士兵 X,Y,Z&#xff08;一开始可以认为都为 0&#xff09;。 游戏有 n 个可能会发生的事件&#xff0c;每个事件之间相互独立且最多只会发生一次&#xff0c;当第 i个事件发生时会分别让 X,Y,Z 增加 Ai,Bi…

elasticsearch6.6.0设置访问密码

elasticsearch6.6.0设置访问密码 第一步 x-pack-core-6.6.0.jar第二步 elasticsearch.yml第三步 设置密码 第一步 x-pack-core-6.6.0.jar 首先破解 x-pack-core-6.6.0.jar 破解的方式大家可以参考 https://codeantenna.com/a/YDks83ZHjd 中<5.破解x-pack> 这部分 , 也可…

AutoRuns下载安装使用教程(图文教程)超详细

「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 AutoRuns 是微软提供的一款「启动项管理」工具&#xff0c;可以检查开机自动加载的所有程…

Spring Cloud 微服务中 gateway 网关如何设置健康检测端点

主要是为了让 k8s 识别到网关项目已经就绪&#xff0c;但是又不想在里面通过 Controller 实现。因为在 Controller 中这样做并不是最佳实践&#xff0c;因为 Gateway 的设计初衷是专注于路由和过滤&#xff0c;而不是业务逻辑的处理。 在 Gateway 中配置健康检查端点可以通过以…

【数据结构和算法】奇偶链表

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一&#xff1a;分离节点后合并 三、代码 3.1 方法一&#xff1a;分离节点后合并 四、复杂度分…

x-cmd pkg | fanyi - 命令行中英文翻译工具

目录 简介首次用户功能特点竞品和相关作品进一步探索 简介 fanyi 是命令行翻译工具&#xff0c;翻译数据来源于 icba.com 和 fanyi.youdao.com&#xff0c;仅支持中英文互译。支持 ChatGPT&#xff0c;可通过设置 OpenAI API 密钥以启用 ChatGPT 翻译。 注意&#xff1a;在 L…

软件测试——黑盒测试

1.测试概述 1.1综述 本测试报告为计算机程序能力在线测评系统的黑盒测试&#xff0c;黑盒测试可以在不知道程序内部结构和代码的情况下进行&#xff0c;用来测试软件功能是否符合用户需求&#xff0c;是否达到用户预期目标&#xff0c;是否拥有较好的人机交互体验。 图1.1 黑…

C语言从入门到实战——文件操作

文件操作 前言一、 为什么使用文件二、 什么是文件2.1 程序文件2.2 数据文件2.3 文件名 三、 二进制文件和文本文件四、 文件的打开和关闭4.1 流和标准流4.1.1 流4.1.2 标准流 4.2 文件指针4.3 文件的打开和关闭4.4 文件的路径 五、 文件的顺序读写5.1 顺序读写函数介绍fgetcfp…

zoj 3494 BCD Code 数位DP + AC自动机

BCD Code 题意 将十进制数的每一位数位转化成一个 4 4 4 位的二进制数&#xff0c;并给定一些 禁止码&#xff0c;规定符合条件的数字的二进制表示中不能包含连续的某个禁止码。问 [ l , r ] [l,r] [l,r] 中有多少个符合条件的数字 思路 朴素的数位 D P DP DP 只涉及少量…

Rancher部署k8s集群测试安装nginx(节点重新初始化方法,亲测)

目录 一、安装前准备工作计算机升级linux内核时间同步Hostname设置hosts设置关闭防火墙&#xff0c;selinux关闭swap安装docker 二、安装rancher部署rancher 三、安装k8s安装k8s集群易错点&#xff0c;重新初始化 四、安装kutectl五、测试安装nginx工作负载 一、安装前准备工作…