当前头条:观察者模式(Observer Pattern)

2023-05-22 19:25:16 来源:博客园
一、模式动机

观察者模式用于描述对象之间的依赖关系,它引入了观察者和观察目标两类不同的角色,由于提供了抽象层,它使得增加新的观察者和观察目标都很方便。观察者模式广泛应用于各种编程语言的事件处理模型中,Java语言也提供了对观察者模式的全面支持。


(相关资料图)

一个对象的状态或行为的变化将导致其他对象的状态或行为也发生改变,它们之间将产生联动定义了对象之间一种一对多的依赖关系,让一个对象的改变能够影响其他对象发生改变的对象称为观察目标,被通知的对象称为观察者一个观察目标可以对应多个观察者二、模式定义观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式观察者模式是一种对象行为型模式三、模式结构

抽象目标类

public abstract class Subject {protected ArrayList observers = new ArrayList();public void attach(Observer observer) {        observers.add(observer);    }public void detach(Observer observer) {        observers.remove(observer);    }public abstract void notify( );}

具体目标类

public class ConcreteSubject extends Subject {    //实现通知方法    public void notify() {        for(Object obs:observers) {            ((Observer)obs).update();        }    }}

抽象观察者类

public interface Observer {    public void update();}

具体观察者类

public class ConcreteObserver implements Observer {    public void update() {        ……    }}
四、案例实现案例背景

股票

案例结构代码实现

抽象目标类:股票

public interface Stocks {    ArrayList OBSERVERS = new ArrayList<>();    void attach(Observer observer);    void detach(Observer observer);    void notifyInvestor();}

目标类:股票

public class Stock implements Stocks{    private String stockName;    private int price;    public Stock(String stockName, int price) {        this.stockName = stockName;        this.price = price;    }    public Stock() {    }    public String getStockName() {        return stockName;    }    public void setStockName(String stockName) {        this.stockName = stockName;    }    public int getPrice() {        return price;    }    public void setPrice(int price) {        this.price = price;    }    @Override    public void attach(Observer observer) {        OBSERVERS.add(observer);    }    @Override    public void detach(Observer observer) {        OBSERVERS.remove(observer);    }    @Override    public void notifyInvestor() {        if(price >= 25*1.05 || price <= 25*0.95){            System.out.println("通知:股票价格变动幅度超过5%!");            for (Observer observer: OBSERVERS) {                observer.upDate();            }        } else {            System.out.println("股票价格变化幅度没有超过5%!!");        }    }}

抽象观察者类

public interface Observer {    void upDate();}

具体观察者类A

public class ConcreteObserverA implements Observer {    private String name;    private Stock stock;    public ConcreteObserverA(String name, Stock stock) {        this.name = name;        this.stock = stock;    }    public ConcreteObserverA(String name) {        this.name = name;    }    @Override    public void upDate() {        System.out.println("通知"+name+":"+stock.getStockName()+"的股票价格变化幅度超过5%,股票价格为:"+stock.getPrice());    }}

具体观察者类B

public class ConcreteObserverB implements Observer {    private String name;    public ConcreteObserverB(String name, Stock stock) {        this.name = name;        this.stock = stock;    }    public ConcreteObserverB(String name) {        this.name = name;    }    private Stock stock;    @Override    public void upDate() {        System.out.println("通知"+name+":"+stock.getStockName()+"的股票价格变化幅度超过5%,股票价格为:"+stock.getPrice());    }}

具体观察者类C

public class ConcreteObserverC implements Observer {    private String name;    private Stock stock;    public ConcreteObserverC(String name, Stock stock) {        this.name = name;        this.stock = stock;    }    public ConcreteObserverC(String name) {        this.name = name;    }    @Override    public void upDate() {        System.out.println("通知"+name+":"+stock.getStockName()+"的股票价格变化幅度超过5%,股票价格为:"+stock.getPrice());    }}

测试类

public class Test {    public static void main(String[] args) {        System.out.println("设计模式,2020006924,于鑫");        Stock stock1 = new Stock("股票1",25);        System.out.println(stock1.getStockName()+"的股价为:"+stock1.getPrice());        Observer obs1,obs2,obs3;        obs1 = new ConcreteObserverA("smith",stock1);        obs2 = new ConcreteObserverB("tom",stock1);        obs3 = new ConcreteObserverC("李白",stock1);        stock1.attach(obs1);        stock1.attach(obs2);        stock1.attach(obs3);        stock1.setPrice(22);        stock1.notifyInvestor();    }}
案例结果五、模式分析有时候在具体观察者类ConcreteObserver中需要使用到具体目标类ConcreteSubject中的状态(属性),会存在关联或依赖关系如果在具体层之间具有关联关系,系统的扩展性将受到一定的影响,增加新的具体目标类有时候需要修改原有观察者的代码,在一定程度上违背了开闭原则,但是如果原有观察者类无须关联新增的具体目标,则系统扩展性不受影响六、总结模式优点可以实现表示层和数据逻辑层的分离在观察目标和观察者之间建立一个抽象的耦合支持广播通信,简化了一对多系统设计的难度符合开闭原则,增加新的具体观察者无须修改原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便模式缺点将所有的观察者都通知到会花费很多时间如果存在循环依赖时可能导致系统崩溃没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而只是知道观察目标发生了变化使用情形一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中使它们可以各自独立地改变和复用一个对象的改变将导致一个或多个其他对象发生改变,且并不知道具体有多少对象将发生改变,也不知道这些对象是谁需要在系统中创建一个触发链

标签

大米等库存充足!宁波生活必需品市场供应总体平稳有序

宁波市商务局9月14日晚间发布的重点生活必需品市场供应情况保障工作日报显示,我市大米、蔬菜、副食、粮...

2022-09-15 17:27:29

全国新能源汽车下乡活动在昆山启动 将发放500万元“红包”

6月17日,由中国汽车工业协会、省工信厅、省农业农村厅、省商务厅、省发改委、苏州市政府、新华日报社、...

2022-06-20 16:48:35

安阳本土确诊病例上升至26例

  中新网安阳1月10日电 (杨大勇)10日,河南省安阳市召开新冠肺炎疫情防控工作第二场新闻发布会通报称...

2022-01-10 15:22:56

3次推迟婚期 满洲里抗疫民警兑现承诺:“我回来娶你了!”

  (抗击新冠肺炎)3次推迟婚期 满洲里抗疫民警兑现承诺:“我回来娶你了!”  中新网呼伦贝尔1月10...

2022-01-10 15:22:56

上海公安民警在岗位上迎接2022年“中国人民警察节”

  中新网上海1月10日电(记者 李姝徵)“我志愿成为中华人民共和国人民警察,献身于崇高的人民公安事业...

2022-01-10 15:22:55

郑州核酸检测为中小学生开辟“绿色通道”

  (抗击新冠肺炎)郑州核酸检测为中小学生开辟“绿色通道”  中新网郑州1月10日电(杨大勇)“学生不用...

2022-01-10 15:22:55

反扒便衣警察“小曹”:藏在人海中的隐形“守护者”

  小曹说,他现在理解了师父当年如何历练出一副“火眼”,碰见的贼多了,案子经手的多了,自然就有了...

2022-01-10 15:22:54

哥哥移植肾脏给病重弟弟 已在上海顺利康复

  中新社上海1月10日电 (陈静 王根华)在上海武警服役的弟弟被尿毒症击倒,哥哥义无反顾地捐献出自...

2022-01-10 15:22:54

网友与人裸聊被敲诈10万余元 被告人获刑5年

  中新网长春1月10日电 (谭伟旗)当下,新型网络诈骗案件已较为普遍,由于网络上身份的不确定性、语言...

2022-01-10 15:22:53

1月10日起天津市暂停开展旅行社旅游业务活动

  中新网1月10日电 据天津市文旅局官网消息,天津市文化和旅游局10日发布紧急通知称,即日起,天津市...

2022-01-10 15:22:53
x 广告
x 广告

Copyright  2015-2022 青年粮油网版权所有  备案号:皖ICP备2022009963号-20   联系邮箱:39 60 291 42@qq.com