【行为型模式】观察者模式

embedded/2024/10/19 9:33:05/

一、观察者模式概述​

        软件系统其实有点类似观察者模式,目的:一个对象的状态或行为的变化将导致其他对象的状态或行为也发生改变,他们之间将产生联动

        观察者模式属于对象行为型

  •         1.定义了对象之间一种一对多的依赖关系,让一个对象的改变能够影响其他对象。
  •         2.发生改变的对象称为观察目标,被通知的对象成为观察者。
  •         3.一个观察目标可以对应多个观察者。别名:发布-订阅(Public/subscribe)模式,模型-视图(Model/View)模式,源-监听器(Source/Listener)模式,从属者(Dependents)模式。

        观察模式的优缺点

  •         优点
    • 1.可以实现表示层和数据逻辑层的分离。
    • 2.在观察目标和观察者之间建立了一个抽象的耦合。
    • 3.支持广播通信,简化了一对多系统设计的难度。
    • 4.符合开闭原则,添加新的具体观察者无须修改与原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便。
  •         缺点
    • 1.将所有的观察者都通知到会花费很多时间。
    • 2.如果存在循环依赖时可能会导致系统崩溃。
    • 3.没有相应得机制让观察者知道所观察得目标对象是怎么发生变化得,而只是知道观察目标发生了变化。
  •         适用环境
    • 1.一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将两个方面封装在独立得对象中方使它们可以各自独立地改变和复用。
    • 2.一个对象的改变将导致一个或多个其他对象发生改变,且并不知道具体有多少个对象将发生改变,也不知道这些对象是谁。
    • 3.需要在系统中创建一个触发链。

二、代码实现

  主题(Subject)+观察者(Observer)=观察者模式

        观察者模式的代码结构包含

  • 抽象主题(Subject):接口,抽象类;
  • 具体主题(ConcreteSubject):比如公众号;
  • 抽象观察者(Observer);
  • 具体观察者(ConcreteObserver);
        2.1 战队控制实现代码
        2.1.1 抽象主题用抽象类实现(抽象类类名AllyControlCenter)
java">package Observe.ally;import java.util.*;//战队控制中心类:目标抽象类
public abstract class AllyControlCenter {protected String allyName;//战队名称//定义一个玩家集合protected ArrayList<Observer> players =new ArrayList<Observer>();public String getAllyname() {return allyName;}public void setAllyname(String allyName) {this.allyName = allyName;}//注册方法public void join(Observer obs) {System.out.println(obs.getName()+"加入"+this.allyName+"战队!");players.add(obs);}//注销方法public void quit(Observer obs) {System.out.println(obs.getName()+"退出"+this.allyName+"战队!");players.remove(obs);}//声明抽象通知方法public abstract void notifyObserver(String name);
}
        2.1.2 具体主题实现(ConcreteAllyControlCenter)
java">package Observe.ally;public class ConcreteAllyControlCenter extends AllyControlCenter {public ConcreteAllyControlCenter(String allyName) {System.out.println(allyName+"战队组建成功!");System.out.println("-------------------------");this.allyName = allyName;}@Overridepublic void notifyObserver(String name) {// TODO 自动生成的方法存根System.out.println(this.allyName+"战队紧急通知,盟友"+name+"遭受敌人袭击!");//遍历观察者集合,调用每一个盟友(自己除外)的支援方法for(Object obs : players) {if(!((Observer)obs).getName().equalsIgnoreCase(name)) {((Observer)obs).help();}}}}
        2.1.3 抽象观察类(接口实现,接口名为Observer)
java">package Observe.ally;
//抽象观察类
public interface Observer {public String getName();public void setName(String name);public void help();//声明支援盟友方法//声明遭受攻击方法public void beAttacked(AllyControlCenter acc);
}
        2.1.4 具体观察者(Player)
java">package Observe.ally;public class Player implements Observer{private String name;public Player(String name) {this.name =name;}public String getName() {return name;}public void setName(String name) {this.name = name;}//支援盟友方法的实现public void help() {System.out.println("坚持住:"+this.name+"来救你!");}//遭受攻击方法的实现,当遭受攻击时将调用战队控制中心的通知方法notifyObserver()来通知public void beAttacked(AllyControlCenter acc) {System.out.println(this.name+"被攻击!");acc.notifyObserver(name);}
}
        2.1.5 main方法调用实现观察者模式
java">package Observe.ally;public class Client {public static void main(String[] args) {// TODO 自动生成的方法存根//定义观察者目标对象AllyControlCenter acc;acc= new ConcreteAllyControlCenter("金庸群侠");//定义四个观察者对象Observer player1,player2,player3,player4;player1 = new Player("杨过");acc.join(player1);player2 = new Player("令狐冲");acc.join(player2);player3 = new Player("张无忌");acc.join(player3);player4 = new Player("段誉");acc.join(player1);//某成员遭受攻击player1.beAttacked(acc);}}
        2.1.6 UML图

        2.2 公众号代码实现
        2.2.1 抽象主题用抽象接口实现(抽象接口名Subject)
java">package Observe.Weixin_observation;
//公众号,主题对象
public interface Subject {//注册public void registerObserver(Observer o);//删除public void removeObserver(Observer o);//通知用户public void notifyObservers(String message);
}
        2.2.2 具体主题实现(WeixinSubject
java">package Observe.Weixin_observation;import java.util.*;public class WeixinSubject implements Subject {private List<Observer> users = new ArrayList<Observer>();String msg;@Overridepublic void registerObserver(Observer o) {// TODO 自动生成的方法存根users.add(o);}@Overridepublic void removeObserver(Observer o) {// TODO 自动生成的方法存根int i = users.indexOf(o);if(i>=0)users.remove(i);}@Overridepublic void notifyObservers(String message) {// TODO 自动生成的方法存根//冒号表示范围==Observer必须在users里面for(Observer o:users) {o.update(message);}}//更新信息public void setMsg(String msg) {this.msg = msg;notifyObservers(msg);}
}
        2.2.3 抽象观察类(接口实现,接口名为Observer)
java">package Observe.Weixin_observation;public interface Observer {//发送文本信息,推送public void update(String message);
}
        2.2.4 具体观察者(WeixinUser)
java">package Observe.Weixin_observation;public class WeixinUser implements Observer {String name;public WeixinUser(String name) {super();this.name = name;}@Overridepublic void update(String message) {// TODO 自动生成的方法存根System.out.println(name+",您好!"+message);}//关注/订阅公众号public void subscribeSubject(Subject o) {o.registerObserver(this);}//取消订阅public void deleteSubject(Subject o) {o.removeObserver(this);}
}
        2.2.5 main方法调用实现观察者模式
java">package Observe.Weixin_observation;public class Test {public static void main(String[] args) {// TODO 自动生成的方法存根//创建一个微信公众号WeixinSubject hdjdlgxydxfy = new WeixinSubject();WeixinUser user1 = new WeixinUser("user1");WeixinUser user2 = new WeixinUser("user2");WeixinUser user3 = new WeixinUser("user3");//用户关注user1.subscribeSubject(hdjdlgxydxfy);user2.subscribeSubject(hdjdlgxydxfy);user3.subscribeSubject(hdjdlgxydxfy);//推送消息hdjdlgxydxfy.setMsg("学院2020年体育课开始选课拉.....");//取消订阅user1.deleteSubject(hdjdlgxydxfy);hdjdlgxydxfy.setMsg("学院2020年体育课结束,下面是选课名单...");}}
        2.2.6 UML图

三、代码结构图


http://www.ppmy.cn/embedded/11581.html

相关文章

Excel文件转Asc文件

单个转换 import os import pandas as pdfilename (10)result01-1.xlsx df pd.read_excel(filename) # 读取Excel文件# 将数据保存为ASC格式 asc_filename os.path.splitext(filename)[0] .asc # 获取文件名并替换扩展名 with open(asc_filename, w) as file:# 写入文件…

线性代数基础2矩阵

矩阵是什么 矩阵就是二维数组&#xff0c;下面是一个 m 乘 n 的矩阵&#xff0c;它有 m 行&#xff0c;n 列&#xff0c;每行每列上面都有元素&#xff0c;每个元素都有行标i 和列标 j&#xff0c; a ij 。简称m n矩阵&#xff0c;记作&#xff1a; 注意a11的索引是 A[0,0]。…

Midjourney是什么?Midjourney怎么用?怎么注册Midjourney账号?国内怎么使用Midjourney?多人合租Midjourney拼车

Midjourney是什么 OpenAI发布的ChatGPT4引领了聊天机器人的竞争浪潮&#xff0c;随后谷歌推出了自己的AI聊天机器人Bard&#xff0c;紧接着微软推出了Bing Chat&#xff0c;百度也推出了文心一言&#xff0c;这些聊天机器人的推出&#xff0c;标志着对话式AI技术已经达到了一个…

17.Nacos与Eureka区别

Nacos会将服务的提供者分为临时实例和非临时实例。默认为临时实例。 临时实例跟eureka一样&#xff0c;会向注册中心报告心跳监测自己是否还活着。如果不正常了nacos会剔除临时实例。&#xff08;捡来的孩子&#xff09; 非临时实例&#xff0c;nacos会主动询问服务提供者是否…

大小端解释以及如何使用程序判断IDE的存储模式

今天让我们来了解一下大小端的概念吧 什么是大小端&#xff1f; 大端&#xff08;存储&#xff09;模式&#xff1a;指的是数据的低位保存在内存的高地址处&#xff0c;而数据的高位则保存在内存的低地址处。 小端&#xff08;存储&#xff09;模式&#xff1a;指的是数据的低位…

MariaDB简介

MariaDB是一个关系数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;是MySQL的一个分支&#xff0c;主要由开源社区维护和开发。 一&#xff0c; MariaDB的来历 1. **起源**&#xff1a;MariaDB的诞生与MySQL的所有权变更有关。MySQL最初由MySQL AB公司开发&#xff…

SpringBoot整合Swagger2

SpringBoot整合Swagger2 1.什么是Swagger2&#xff1f;&#xff08;应用场景&#xff09;2.项目中如何使用2.1 导入依赖2.2 编写配置类2.3 注解使用2.3.1 controller注解&#xff1a;2.3.2 方法注解2.3.3 实体类注解2.3.4 方法返回值注解2.3.5 忽略的方法 3.UI界面 1.什么是Swa…

线性模型算法

简介 本文章介绍机器学习中的线性模型有关内容&#xff0c;我将尽可能做到详细得介绍线性模型的所有相关内容 前置 什么是回归 回归的就是整合&#xff0b;预测 回归处理的问题可以预测&#xff1a; 预测房价 销售额的预测 设定贷款额度 可以根据事物的相关特征预测出对…