首页 > 其他分享 >学习记录-观察者模式

学习记录-观察者模式

时间:2023-01-12 00:00:36浏览次数:61  
标签:记录 对象 void 观察者 模式 static ZhangSan public

观察者模式

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern),也称之为发布-订阅模式。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式

介绍

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

如何解决:使用面向对象技术,可以将这种依赖关系弱化。

关键代码:在抽象类里有一个 ArrayList 存放观察者们。

应用实例: 1、拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。 2、西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。

优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。

缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景:

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

注意事项: 1、JAVA 中已经有了对观察者模式的支持类。 2、避免循环引用。 3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

实现

类图

image-20230111224958504

代码实现

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        //定义借款方张三
        Debit zhangsan=new ZhangSan();
        //张三去借钱,朝谁借钱?朝赵四、王五借钱
        zhangsan.borrow(new ZhaoSi());
        zhangsan.borrow(new WangWu());

        //借完之后,过了一段时候张三买彩票中了五百万,又成了有钱了,即状态改变了
        //status改变
        System.out.println("ZhangSan有钱了,状态已改变");
        //可以通知所有的贷款方,这样贷款方就可以向张三要回钱了
        zhangsan.notifyCredits();
    }

    //首先我们来定义借款方的接口,Debit
    interface Debit{
        //定义一个借方法,向贷款方借钱
        void borrow(Credit credit);
        //定义一个通知方法,通知所有的贷款方我有钱了,可以向你们还钱了
        void notifyCredits();
    }

    //定义一个借款方,ZhangSan,实现借款方的接口
    //注:这里static修饰知识因为在main函数里调用了相关函数,并无其它意义。
    static class ZhangSan implements Debit{
        //我们的贷款方肯定不止一个人吧,所以我们定义一个数据结构来维护所有的贷款方
        private List<Credit> allCredits=new ArrayList<>();
        public Integer state=0;    //设置状态,0表示没钱,1表示有钱

        public void setAllCredits(List<Credit> allCredits) {
            this.allCredits = allCredits;
        }

        //然后在借钱的时候往列表里面添加贷款方即可
        //在学术上来讲即添加一个观察者对象,也就是说贷款方就是一个观察者,他观察我的状态,比如我有钱还是没钱
        @Override
        public void borrow(Credit credit) {
            allCredits.add(credit);
            System.out.println("ZhangSan借钱+1");
        }

        //最后有一个通知机制,一旦我有钱了,就向所有的贷款方通知,让他们去找我们要钱就可以了
        @Override
        public void notifyCredits() {
            allCredits.forEach(credit -> credit.takeMoney());
        }
    }


    //定义一个贷款方接口
    interface Credit{
        //定义一个要钱的方法
        void takeMoney();
    }

    //实现几个贷款方
    //注:这里static修饰知识因为在main函数里调用了相关函数,并无其它意义。
    static class ZhaoSi implements Credit{
        @Override
        public void takeMoney() {
            System.out.println("ZhaoSi要钱");
        }
    }
    //注:这里static修饰知识因为在main函数里调用了相关函数,并无其它意义。
    static class WangWu implements Credit{
        @Override
        public void takeMoney() {
            System.out.println("Wangwu要钱");
        }
    }

}

运行结果

ZhangSan借钱+1
ZhangSan借钱+1
ZhangSan有钱了,状态已改变
ZhaoSi要钱
Wangwu要钱

此文章参考:

【菜鸟教程】:https://www.runoob.com/design-pattern/observer-pattern.html
【五分钟学设计模式.07.观察者模式-哔哩哔哩】: https://b23.tv/ILb4GpR

标签:记录,对象,void,观察者,模式,static,ZhangSan,public
From: https://www.cnblogs.com/galo/p/17045239.html

相关文章

  • 1.11刷题记录
    1.Yesecnodrumsticks1根据题目提示得知本题是lsb隐写打开附件得到一张图片用stegsolve打开flag{Yesec_1s_lsb}2.qsdz'sgirlfriend1根据题目提示得知:flag......
  • 记录一种独特的特殊网络流处理方式
    考虑如下抽象而来的问题:你有若干物品,每个物品都有两种属性。现在你想把他们分成若干组,使得每组内物品至少某种属性都相同,使得\(\sum_iS_i^2\)组大小平方和最大。利用......
  • 学习记录-适配器模式
    适配器模式适配器模式(AdapterPattern)是作为两个不兼容的接口之间的桥梁,它不会改变原先的接口。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。这种模式......
  • 设计模式(二)----软件设计原则
    在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,要尽量根据7条原则来开发程序,从而提高软件开发效率、节约软件开发成本和维护成本。1、单一......
  • 路由传参,路由重定向和模式,编程式导航,编程式导航传参
    路由传参先配置好路由在父组件种添加<template><divclass="footer_wrap"><!--头部点击--><div><router-linkto="/practice1">点击测试1</router......
  • 玩转Vben Admin第2改:配置权限模式
    Vben设计了2种权限模式,分别是【前端角色权限(ROLE)】和【后端动态获取(BACK)】 详细说明请参考https://doc.vvbin.cn/guide/auth.html为了打造【轻前端重后端】我们希望......
  • 学习记录-装饰器模式
    装饰器模式装饰器模式(DecoratorPattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式......
  • 【编程】大端小端模式
    一句话:低位的数据保存到高位上,就是装大尾巴狼,就是大端。 数据:11223344(尾端是44)保存在寄存器:(左边是高地址)44332211  (右边是低地址) --大端保存在寄存器:(左边是高地址......
  • 网络流 24 题做题记录
    网络流24题做题记录P3254圆桌问题源点连单位,容量为单位人数,桌子连汇点,容量为桌子容量,各单位连各桌子,容量为\(1\),因为每个单位在每张桌子上最多\(1\)人,跑最大流。P......
  • buuctf-preg_replace的e模式造成命令执行
    [BJDCTF2020]ZJCTF,不过如此打开后是正常的代码审计首先第一眼看到的就是file_get_contents而且还对$text有要求,直接上伪协议data://text/plain,Ihaveadream,同时按照......