Java微服务-设计模式系列全套文章-观察者模式(Observer Pattern)

Java微服务-设计模式系列全套文章-观察者模式(Observer Pattern)一 模式动机观察者模式用于描述对象之间的依赖关系 它引入了观察者和观察目标两类不同的角色 由于提供了抽象层 它使得增加新的观察者和观察目标都很方便 观察者模式广泛应用于各种编程语言的事件处理模型中 Java 语言也提供了对观察者模式的全面支持

欢迎大家来到IT世界,在知识的湖畔探索吧!

一、模式动机

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

  • 一个对象的状态或行为的变化将导致其他对象的状态或行为也发生改变,它们之间将产生联动
  • 定义了对象之间一种一对多的依赖关系,让一个对象的改变能够影响其他对象
  • 发生改变的对象称为观察目标,被通知的对象称为观察者
  • 一个观察目标可以对应多个观察者

二、模式定义

  • 观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新
  • 观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式
  • 观察者模式是一种对象行为型模式

三、模式结构

Java微服务-设计模式系列全套文章-观察者模式(Observer Pattern)



欢迎大家来到IT世界,在知识的湖畔探索吧!

抽象目标类

csharp

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

欢迎大家来到IT世界,在知识的湖畔探索吧!

具体目标类

scala

欢迎大家来到IT世界,在知识的湖畔探索吧!public class ConcreteSubject extends Subject { //实现通知方法 public void notify() { for(Object obs:observers) { ((Observer)obs).update(); } } }

抽象观察者类

java

public interface Observer { public void update(); }

具体观察者类

angelscript

欢迎大家来到IT世界,在知识的湖畔探索吧!public class ConcreteObserver implements Observer { public void update() { …… } }

四、案例实现

案例背景

股票

案例结构

Java微服务-设计模式系列全套文章-观察者模式(Observer Pattern)

代码实现

抽象目标类:股票

java

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

目标类:股票

typescript

欢迎大家来到IT世界,在知识的湖畔探索吧!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%!!"); } } }

抽象观察者类

java

public interface Observer { void upDate(); }

具体观察者类A

typescript

欢迎大家来到IT世界,在知识的湖畔探索吧!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

typescript

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

typescript

欢迎大家来到IT世界,在知识的湖畔探索吧!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()); } }

测试类

reasonml

public class Test { public static void main(String[] args) { 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(); } }

案例结果

Java微服务-设计模式系列全套文章-观察者模式(Observer Pattern)

五、模式分析

  • 有时候在具体观察者类ConcreteObserver中需要使用到具体目标类ConcreteSubject中的状态(属性),会存在关联或依赖关系
  • 如果在具体层之间具有关联关系,系统的扩展性将受到一定的影响,增加新的具体目标类有时候需要修改原有观察者的代码,在一定程度上违背了开闭原则,但是如果原有观察者类无须关联新增的具体目标,则系统扩展性不受影响

六、总结

模式优点

  • 可以实现表示层和数据逻辑层的分离
  • 在观察目标和观察者之间建立一个抽象的耦合
  • 支持广播通信,简化了一对多系统设计的难度
  • 符合开闭原则,增加新的具体观察者无须修改原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便

模式缺点

  • 将所有的观察者都通知到会花费很多时间
  • 如果存在循环依赖时可能导致系统崩溃
  • 没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而只是知道观察目标发生了变化

使用情形

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中使它们可以各自独立地改变和复用
  • 一个对象的改变将导致一个或多个其他对象发生改变,且并不知道具体有多少对象将发生改变,也不知道这些对象是谁
  • 需要在系统中创建一个触发链

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/126866.html

(0)
上一篇 26分钟前
下一篇 11分钟前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信