首页 > 其他分享 >观察者模式II

观察者模式II

时间:2023-10-14 12:44:18浏览次数:41  
标签:observer void 观察者 模式 class II new public

需求

以支付状态更新通知为例,当支付状态更新时,通知邮件服务和库存服务。

自定义观察者模式

package com.fh.observer;

import org.junit.Test;

import java.util.List;
import java.util.Vector;

/**
 * 推送模式
 */
public class ObserverTest6 {
    /**
     * 观察者
     */
    public interface Observer {
        void update();
    }

    /**
     * 库存服务
     */
    public class MyStockObserver implements Observer {
        @Override
        public void update() {
            System.out.println("库存服务收到通知");
        }
    }


    /**
     * 邮件服务
     */
    public class MyEmailObserver implements Observer {
        @Override
        public void update() {
            System.out.println("邮件服务收到通知.");
        }
    }

    /**
     * 被观察者
     */
    public interface Subject {
        // 添加观察者
        void addObserver(Observer observer);

        //删除观察者
        void removeObserver(Observer observer);

        //通知观察者
        void notifyObservers();
    }

    /**
     * 更改支付状态的被观察则
     */
    public class MyPaymentStatusUpdateSubject implements Subject {

        private List<Observer> observers = new Vector<>();

        @Override
        public void addObserver(Observer observer) {
            observers.add(observer);
        }

        @Override
        public void removeObserver(Observer observer) {
            observers.remove(observer);
        }

        @Override
        public void notifyObservers() {
            for (Observer observer : observers) {
                observer.update();
            }
        }

        public void updatePaymentStatus(int newStatus) {

            // 业务逻辑操作
            System.out.println("更新新的支付状态为:" + newStatus);

            // 通知观察者
            this.notifyObservers();
        }
    }

    @Test
    public void m() {

        // "支付状态更新"->看做一个事件,可以被监听的事件

        // 被观察者。即事件源
        MyPaymentStatusUpdateSubject myPaymentStatusUpdateSubject = new MyPaymentStatusUpdateSubject();

        // 观察者。即事件监听器
        MyEmailObserver myEmailObserver = new MyEmailObserver();
        MyStockObserver myStockObserver = new MyStockObserver();

        // 添加观察者。
        myPaymentStatusUpdateSubject.addObserver(myEmailObserver);
        myPaymentStatusUpdateSubject.addObserver(myStockObserver);

        // 发布事件。支付状态更新。
        myPaymentStatusUpdateSubject.updatePaymentStatus(2);
    }
}

jdk中的观察者模式

JDK已经帮我们实现了一个观察者模式,事件收集器采用Vector容器保存,操作事件收集器的方法都是线程安全的。

我们针对JDK给出的观察者模式的解决方案总结几点:
1、Observable实现了大部分的逻辑,没有很好地进行抽象,灵活性降低了
2、存在2个潜在的问题:一个刚刚加入的观察者错过了通知;一个刚刚删除的观察者被错误的通知
3、Observable实现的方法采用synchronized,操作同一个方法时串行,可能会存在效率问题

package com.fh.observer;

import org.junit.Test;

import java.util.*;

public class ObserverTest7 {

    /**
     * 邮件服务
     */
    public class EmailObserver implements Observer {
        @Override
        public void update(Observable o, Object arg) {
            System.out.println("邮件服务收到通知");
        }
    }

    /**
     * 库存服务
     */
    public class StockObserver implements Observer {
        @Override
        public void update(Observable o, Object arg) {
            System.out.println("库存服务收到通知");
        }
    }

    /**
     * 支付状态变更做为一个可观察者
     */
    public class PaymentStatusObservable extends Observable {

        public void updatePaymentStatus(int newStatus) {
            // 业务逻辑操作
            System.out.println("更新新的支付状态为:" + newStatus);

            // 通知观察者
            this.setChanged();//需要调用一下这这方法,表示被观察者的状态已发生变更,Observable才会通知观察者
            this.notifyObservers();
        }
    }

    //使用JDK中的观察者模式
    @Test
    public void m() {
        // "支付状态更新"->看做一个事件,可以被监听的事件

        // 被观察者。即事件源
        PaymentStatusObservable paymentStatusObservable = new PaymentStatusObservable();

        // 添加观察者
        paymentStatusObservable.addObserver(new EmailObserver());
        paymentStatusObservable.addObserver(new StockObserver());

        // 支付状态变更
        paymentStatusObservable.updatePaymentStatus(3);
    }
}

JavaBean中的事件驱动

原理解析
javabean规范中提供了一种监听属性变化的事件驱动模型。提供操作Javabean属性的类PropertyChangeSupport和PropertyEditorSupport。

从事件驱动模型的各个构建来分析,PropertyChangeSupport和PropertyEditorSupport都属于事件源,能够产生事件。如果以观察模式的角度来看,则是被观察者

事件监听器实现PropertyChangeListener接口,通过PropertyChangeSupport和PropertyEditorSupport添加到事件队列中。

一旦有Javabean属性发生变化通过调用PropertyChangeSupport#firePropertyChange()、PropertyEditorSupport#firePropertyChange()即可触发监听器处理事件。

package com.fh.observer;

import org.junit.Test;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyChangeEvent;

public class ObserverTest8 {


    /**
     *从事件驱动模型的各个构建来分析,PropertyChangeSupport和PropertyEditorSupport都属于事件源,能够产生事件。
     * 如果以观察模式的角度来看,则是被观察者
     */
    public class PaymentStatusUpdateBean {

        PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);

        public void updateStatus(int newStatus) {
            // 模拟业务逻辑
            System.out.println("支付状态更新: " + newStatus);
            // 触发通知 一旦有Javabean属性发生变化通过调用PropertyChangeSupport#firePropertyChange()
            propertyChangeSupport.firePropertyChange("paymentStatuUpdate", 0, newStatus);
        }

        public void addPropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.addPropertyChangeListener(listener);
        }

        public void removePropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.addPropertyChangeListener(listener);
        }
    }


    /**
     * 支付状态变更的监听器
     *
     * 事件监听器实现PropertyChangeListener接口,
     * 通过PropertyChangeSupport和PropertyEditorSupport添加到事件队列中。
     */
    public class PaymentStatusUpdateListener implements PropertyChangeListener {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            System.out.printf("支付状态变更. eventName : %s, oldValue : %s, newValue : %s", evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
        }
    }

    //测试JDK提供的PropertyChangeEvent
    @Test
    public void m() {
        PaymentStatusUpdateBean paymentStatusUpdateBean = new PaymentStatusUpdateBean();

        // 添加监听器
        paymentStatusUpdateBean.addPropertyChangeListener(new PaymentStatusUpdateListener());

        // 更新支付状态
        paymentStatusUpdateBean.updateStatus(3);
    }

}

Spring事件驱动

标签:observer,void,观察者,模式,class,II,new,public
From: https://www.cnblogs.com/haveanicedayfh/p/17764020.html

相关文章

  • 手把手教你分析IIS日志——IP访问次数,URI访问统计等
    配置IIS网站的日志下载日志分析工具https://gitee.com/tangdd369098655/open-network-disk解压打开选择文件指定分析规则(还可以自己写规则哦~~)运行规则进行分析今天就写到这里啦~小伙伴们,( ̄ω ̄( ̄ω ̄〃( ̄ω ̄〃)ゝ我们明天再见啦~~大家要天天开心哦欢迎大家指出文章需......
  • 建造者模式--Java实现
    画类图具体代码实现//Computer.javapackageorg.example.design003;publicclassComputer{publicComputer(StringCPU,StringRAM,Stringhard,Stringhost){this.CPU=CPU;this.RAM=RAM;Hard=hard;Host=host;......
  • 抽象工厂模式--C++实现
    具体代码实现#include<iostream>usingnamespacestd;classMan{public:virtualvoidshow()=0;};classWoman{public:virtualvoidshow()=0;};classYellowMan:publicMan{public:virtualvoidshow(){cout<<"......
  • 抽象工厂模式--Java实现
    画类图用人的肤色和性别进行抽象工厂方法模式的实现,肤色和性别组成产品等级结构和产品族;具体代码实现项目结构://AbstractFactory.javapackageorg.example.design002;publicinterfaceAbstractFactory{publicMancreateMan();publicWomancreateWoman();}......
  • 状态模式
    状态模式案例引入APP抽奖活动请编写抽象完成APP抽奖活动,具体要求如下:1.假如每参加一次这个活动要扣除用户50积分,中将概率是10%。2.奖品数量固定,抽完就不能抽了。3.活动状态有四个,分别是,可以抽奖,不能抽奖,发送奖品,奖品已领完。4.活动的状态转换图基本介绍1.状态模式(State......
  • 【愚公系列】2023年10月 二十三种设计模式(十二)-代理模式(Proxy Pattern)
    ......
  • 工厂方法模式--Java代码实现
    1、画类图2、Java代码实现其中可知,PWFactory、PW类均为接口类;并且,DESFactory、IDEAFactory类均要实现PWFactory接口;DES、IDEA类均要实现PW接口;具体代码如下://PWFactory.javapackageorg.example;publicinterfacePWFactory{publicPWcreateProduce();}//DE......
  • c++工厂模式和抽象工厂模式的区别是什么
    C++中的工厂模式和抽象工厂模式都是为了实现对象的创建和实例化,但它们在设计和使用方式上有一些区别。工厂模式(FactoryPattern):工厂模式通过一个工厂类来封装对象的创建逻辑,并将具体对象的创建细节隐藏起来。客户端只需通过工厂类调用相应的方法来获取所需的对象实例。工厂模式......
  • Repository模式【转】
    最近开发的MVC项目使用了Repository模式。啥是Repository模式? 从图看,有一个仓库接口,一个实现了这个仓库接口的基类;然后在使用方,一方面,要声明一个继承于仓库接口的子接口,另一方面,编写一个数据库操作类,继承仓库基类,并实现这个子接口。继承仓库基类容易理解,为啥还要搞一个子接口......
  • 简单工厂模式--Java实现+C++实现
    问题描述使用简单工厂模式模拟女娲(Nvwa)造人(Person),如果传入参数M,则返回一个Man对象,如果传入参数W,则返回一个Woman对象,如果传入参数R,则返回一个Robot对象。请用程序设计实现上述场景。问题实现用starUML画的相应的类图:然后就是代码实现:Java代码实现在Java里面,Person类相......