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

一、观察者模式概述​

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

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

  •         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)
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)
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)
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)
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方法调用实现观察者模式
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)
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
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)
package Observe.Weixin_observation;public interface Observer {//发送文本信息,推送public void update(String message);
}
        2.2.4 具体观察者(WeixinUser)
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方法调用实现观察者模式
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.hqwc.cn/news/624818.html

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

相关文章

static+单例模式+类的复合继承

汇编语言 汇编语言是最靠谱的验证“编程语言相关知识点”正确性的方式 汇编语言与机器语言一一对应&#xff0c;每一条机器语言都有与之对应的汇编指令 机器语言是计算机使用的语言&#xff0c;它是一串二进制数字 汇编语言可以通过汇编得到机器语言机器语言可以通过反汇编得到…

视频汇聚/安防视频监控云平台EasyCVR云端录像播放与下载的接口调用方法

视频汇聚/安防视频监控云平台EasyCVR支持多协议接入、可分发多格式的视频流&#xff0c;平台支持高清视频的接入、管理、共享&#xff0c;支持7*24小时不间断监控。视频监控管理平台EasyCVR可提供实时远程视频监控、录像、回放与存储、告警、语音对讲、云台控制、平台级联、磁盘…

03.卸载MySQL

卸载MySQL 1.Windows卸载MySQL8 停止服务 用命令停止或者在服务中停止都可以 net stop mysql&#xff08;服务名字可以去服务里面看一下&#xff09;控制面板卸载MySQL 卸载MySQL8.0的程序可以和其他桌面应用程序一样直接在控制面板选择卸载程序&#xff0c;并在程序列表中…

当全连接队列满了,tcp客户端收到服务端RST信令的模拟

当tcp服务端全连接队列满了后&#xff0c;并且服务端也不accept取出连接&#xff0c;客户端再次连接时&#xff0c;服务端能够看到SYN_RECV状态。但是客户端看到的是ESTABLISHED状态&#xff0c;所以客户端自认为成功建立了连接&#xff0c;故其写往服务端写数据&#xff0c;发…

hadoop编程之工资序列化排序

数据集展示 7369SMITHCLERK79021980/12/17800207499ALLENSALESMAN76981981/2/201600300307521WARDSALESMAN76981981/2/221250500307566JONESMANAGER78391981/4/22975207654MARTINSALESMAN76981981/9/2812501400307698BLAKEMANAGER78391981/5/12850307782CLARKMANAGER78391981/…

FPGA在汽车领域的应用简谈

随着科技的不断进步&#xff0c;汽车行业也在不断演变&#xff0c;而FPGA&#xff08;可编程逻辑门阵列&#xff09;的引入给汽车领域带来了革命性的变化。FPGA作为一种灵活且高性能的“处理器”&#xff0c;已经在汽车行业找到了广泛的应用 目前随着新能源汽车的发展&#xff…

UE 录屏自动化上传阿里云OSS

前言 最近在做一个功能&#xff0c;然后就发现了一个很有趣的东西&#xff0c;虽然在一定程度上属于偷懒&#xff0c;但是在一些短频快的应用中还是很适用的&#xff0c;下面我就针对于这个测试做一些简单的分享&#xff0c;希望帮助到大家&#xff0c;在实际的开发中获得一些灵…

吴恩达llama课程笔记:第七课llama安全工具

羊驼Llama是当前最流行的开源大模型&#xff0c;其卓越的性能和广泛的应用领域使其成为业界瞩目的焦点。作为一款由Meta AI发布的开放且高效的大型基础语言模型&#xff0c;Llama拥有7B、13B和70B&#xff08;700亿&#xff09;三种版本&#xff0c;满足不同场景和需求。 吴恩…

Jenkins配置windows/linux从节点

背景&#xff1a; 环境&#xff1a;jenkins环境&#xff08;Ubuntu&#xff09; 节点机器&#xff1a;Linux、Windows 前置条件&#xff1a; 节点机器&#xff1a;安装java、allure、python 1 Linux节点管理机器添加 1.1 系统管理->节点列表->New Node 1.2 节点配置…

万兆以太网MAC设计(5)MAC_TX模块设计以及上板带宽测试

文章目录 前言一、模块功能二、实现方式三、仿真四、上板测速 前言 MAC_RX的设计暂时告一段落&#xff0c;本节将开始进行MAC_TX的设计。 一、模块功能 接收上层用户的AXIS数据&#xff0c;将其转换为XGMII进接口的数据发送给IP核。可接受AXIS数据流&#xff0c;可支持数据包…

Spring Boot集成easypoi快速入门Demo

1.什么是easypoi&#xff1f; Easypoi功能如同名字easy&#xff0c;主打的功能就是容易&#xff0c;让一个没见接触过poi的人员就可以方便的写出Excel导出&#xff0c;Excel模板导出&#xff0c;Excel导入&#xff0c;Word模板导出&#xff0c;通过简单的注解和模板语言(熟悉的…

简单3步,OpenHarmony上跑起ArkUI分布式小游戏

标准系统新增支持了方舟开发框架&#xff08;ArkUI&#xff09;、分布式组网和 FA 跨设备迁移能力等新特性&#xff0c;因此我们结合了这三种特性使用 ets 开发了一款如下动图所示传炸弹应用。 打开应用在通过邀请用户进行设备认证后&#xff0c;用户须根据提示完成相应操作&am…