首页 > 其他分享 >观察者模式(Observer)

观察者模式(Observer)

时间:2023-03-30 23:13:10浏览次数:32  
标签:String Observer void 观察者 模式 new public name

1,观察者模式

  观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。

  又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

2,观察者模式角色

  • Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。

  • ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。

  • Observer:抽象观察者,是观察者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。

  • ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

3,观察者模式 Demo

1,抽象观察者

package com.demo.base.design_partten.observer;

/**
 * 观察者
 * */
public interface Observer {
    /*
    * 订阅内容,接收订阅内容
    * */
    public void attachMsg(String subject, String msg);

}

2,抽象主题

package com.demo.base.design_partten.observer;

/**
 * 主题
 * @author admin
 * */
public interface Subject {

    /**
     * 添加观察者
     * */
    public void attach(Observer observer);

    /**
     * 发布消息
     * */
    public void notify(String msg);

    /**
     * 移除观察者
     * */
    public void detach(Observer observer);
}

3,观察者实现

package com.demo.base.design_partten.observer;

/**
 * 观察者实例
 * */
public class ConcreteObserver implements Observer {

    String name;

    @Override
    public void attachMsg(String subject, String msg) {
        System.out.println(String.format("观察者:%s 收到 %s 发布的消息:%s", name, subject, msg));

        //doSth...
    }

    public ConcreteObserver(){}
    public ConcreteObserver(String name){
        this.name = name;
    }
}

4,主题实现

package com.demo.base.design_partten.observer;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * 主题实现类
 * */
public class ConcreteSubject implements Subject{

    /**
     * 观察者集合
     * */
    private Set<Observer> events = new LinkedHashSet<>();

    //主题名称
    String name;

    @Override
    public void attach(Observer observer) {
        events.add(observer);
    }

    @Override
    public void notify(String msg) {
        for(Observer observer : events){
            observer.attachMsg(name, msg);
        }
    }

    @Override
    public void detach(Observer observe) {
        events.remove(observe);
    }

    public ConcreteSubject(){}
    public ConcreteSubject(String name){
        this.name = name;
    }
}

5,业务类

package com.demo.base.design_partten.observer;

/**
 * 观察者模式:
 * 1,观察者接口
 *    定义订阅方法,用来接收发布的消息
 * 2,观察者实现类
 *    实现订阅方法,接收发布的消息
 * 3,主题接口 subject
 *    定义了添加观察者,删除观察者,发布消息三个接口
 * 4,主题实现类 ConcreteSubject
 *    内部持有一个观察者结合,实现发布消息接口,发布消息时候循环调用观察者订阅方法。
 * 5,测试方法
 *    观察者订阅主题,调用主题的 attach 方法。
 *    主题发布消息,会通知所有观察者
 *
 * */
public class MainTest {
    public static void main(String[] args) {
        ConcreteObserver c1 = new ConcreteObserver("小明");
        ConcreteObserver c2 = new ConcreteObserver("小李");
        ConcreteObserver c3 = new ConcreteObserver("小张");

        ConcreteSubject bos = new ConcreteSubject("老板");
        bos.attach(c1);
        bos.attach(c2);
        bos.attach(c3);
        bos.attach(c1);

        ConcreteSubject s = new ConcreteSubject("家长");
        s.attach(c1);
        s.attach(c2);
        s.attach(c3);

        s.notify("啥时候回来啊");
        bos.notify("国庆都给我加班!");
    }
}

4,发布-订阅模式

相比观察者模式多了订阅中心。

1,发布者

package com.demo.base.design_partten.observer.publish_subscrice;

/**
 * 发布者
 * @author
 * */
public class Publisher {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Publisher(){}
    public Publisher(String name){
        this.name = name;
    }
}

2,订阅者

package com.demo.base.design_partten.observer.publish_subscrice;

/**
 * 订阅者
 * @author admin
 */
public class SubScriber {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public SubScriber(){}
    public SubScriber(String name){
        this.name = name;
    }

    public void getMessage(Publisher publisher, String msg){
        System.out.println(String.format( "订阅者:%s 收到 %s 发布的消息:%s!", name, publisher.getName(), msg) );
    }
}

3,订阅中心接口

package com.demo.base.design_partten.observer.publish_subscrice;

/**
 * @author admin
 * 订阅中心
 */
public interface PublisherCentral {

    //添加发布者-订阅者
    public void addPublisher(Publisher publisher, SubScriber... subScriber);

    //删除发布者-订阅者
    public void removePublisher(Publisher publisher, SubScriber ... subScribers);

    //发布消息
    public void publishMsg(Publisher publisher, String msg);
}

4,订阅中心实现

package com.demo.base.design_partten.observer.publish_subscrice;

import java.util.*;

/**
 * @author admin
 */
public class PublisherCentralImpl implements PublisherCentral {

    private Map<Publisher, Set<SubScriber>> set = new HashMap<>();
    private String name;

    public PublisherCentralImpl(){}
    public PublisherCentralImpl(String name){
        this.name = name;
    }

    @Override
    public void addPublisher(Publisher publisher, SubScriber... subScriber) {
        Set<SubScriber> s = set.get(publisher);
        if(s == null){
            s = new LinkedHashSet<>(Arrays.asList(subScriber));
            set.put(publisher, s);
        }else{
            s.addAll(Arrays.asList(subScriber));
        }
    }

    @Override
    public void removePublisher(Publisher publisher, SubScriber... subScribers) {
        Set<SubScriber> s = set.get(publisher);
        if(s == null){
            return;
        }else{
            s.removeAll(Arrays.asList(subScribers));
        }
    }

    @Override
    public void publishMsg(Publisher publisher, String msg) {
        Set<SubScriber> s = set.get(publisher);
        System.out.println(String.format("%s 在 %s 发布了消息:%s", publisher.getName(), name, msg));
        if(s != null){
            for(SubScriber subScriber : s){
                subScriber.getMessage(publisher, msg);
            }
        }
    }
}

5,业务类

package com.demo.base.design_partten.observer.publish_subscrice;

/**
 * @author 发布-订阅模式
 */
public class MainTest {

    public static void main(String[] args) {

        //订阅中心
        PublisherCentral publisherCentral = new PublisherCentralImpl("报社一");

        Publisher p1 = new Publisher("大河网");
        Publisher p2 = new Publisher("河南网");
        Publisher p3 = new Publisher("东京网");
        publisherCentral.addPublisher(p1, new SubScriber("张三"), new SubScriber("李四"), new SubScriber("王五"));
        publisherCentral.addPublisher(p2, new SubScriber("张三"), new SubScriber("小六"));
        publisherCentral.addPublisher(p3, new SubScriber("join"));
        publisherCentral.publishMsg(p1, "大河网最新报道!");
        publisherCentral.publishMsg(p2, "今年还行!");
        publisherCentral.publishMsg(p3, "bird language!");
    }
}

标签:String,Observer,void,观察者,模式,new,public,name
From: https://www.cnblogs.com/cnff/p/17274692.html

相关文章

  • Spine在Unity 的URP模式下,描边的坑。
    在urp模式下,spine描边需要特殊处理,首先去。官网下载他们的urp拓展包,然后通过packagemanager导入到项目。打开包里outlineshadersurp场景。发现他们实现这个场景的时候,是在spine动画下面套了一个outline对象,这个outline对象有一个脚本叫做renderexistingmesh。将这个脚本......
  • 责任链模式
    概述《设计模式》一书中对于“责任链模式”的意图描述如下:使多个对象有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止一般的UML结构图如下所示:其中,Handler将会包含直接后继处理类succ......
  • 设计模式(三十)----综合应用-自定义Spring框架-自定义Spring IOC-定义bean、注册表相
    现要对下面的配置文件进行解析,并自定义Spring框架的IOC对涉及到的对象进行管理。<?xmlversion="1.0"encoding="UTF-8"?><beans>  <beanid="userService"class="com.itheima.service.impl.UserServiceImpl">    <propertyname=&qu......
  • IOS中KVO模式的解析与应用
    最近老翁在项目中多处用到了KVO,深感这种模式的好处。现总结如下:一、概述KVO,即:Key-ValueObserving,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。KVO其实也是“观察者”设计模......
  • (二十六)访问者模式
    1.概述访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。2.示例Visitor类,为该对象结构中ConcreteElement的每一个类声明一个Visit操作。Visitor.javapublicabstractclassVisitor{......
  • 直线模组常用的驱动模式有哪些?
    直线模组是工业生产中经常用到的直线运动单元,其驱动方式有很多种,但常用的驱动方式通常有两种,一种是滚珠丝杆传动,另一种是同步带传动。滚珠丝杆传动方式的特点是重复定位精度较高,最高精度可达±0.005mm,并且负载一般也比较大,在工业生产中通常被应用于对精度有一定要求的生产过程中。......
  • 单用户模式进centos系统修改root密码
    为虚拟机server重设管理密码1)重启系统,进入recovery恢复模式在读秒时候按e键,找到linux16行,按键盘End末尾添加空格rd.breakconsole=tty0按ctrl+x启动2)......
  • 《无尽之剑2》重大更新 新增ClashMob社交模式
    备受关注的《无尽之剑2》ClashMob模式终于亮相了,已在AppStore上架。ClashMob是一种新游戏模式,这种模式可以多人合作,通过联网和其他玩家一起挑战一个超大型的BOSS。胜利者......
  • 基于stm32mp157 linux开发板ARM裸机开发教程3:Cortex-A7 架构与工作模式(连载中)
    前言:目前针对ARMCortex-A7裸机开发文档及视频进行了二次升级持续更新中,使其内容更加丰富,讲解更加细致,全文所使用的开发平台均为华清远见FS-MP1A开发板(STM32MP157开发板)针对......
  • golang并发编程-模式
    1.Generator9.Queuepackagemainimport("fmt""sync""time")constlimit=4constwork=100funcprocess(wg*sync.WaitGroup,workint,......