一个对象的状态或行为的变化将导致其他对象的状态或行为也发生改变,它们之间将产生联动定义了对象之间一种一对多的依赖关系,让一个对象的改变能够影响其他对象发生改变的对象称为观察目标,被通知的对象称为观察者一个观察目标可以对应多个观察者二、模式定义观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式观察者模式是一种对象行为型模式三、模式结构观察者模式用于描述对象之间的依赖关系,它引入了观察者和观察目标两类不同的角色,由于提供了抽象层,它使得增加新的观察者和观察目标都很方便。观察者模式广泛应用于各种编程语言的事件处理模型中,Java语言也提供了对观察者模式的全面支持。
(相关资料图)
抽象目标类
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中的状态(属性),会存在关联或依赖关系如果在具体层之间具有关联关系,系统的扩展性将受到一定的影响,增加新的具体目标类有时候需要修改原有观察者的代码,在一定程度上违背了开闭原则,但是如果原有观察者类无须关联新增的具体目标,则系统扩展性不受影响六、总结模式优点可以实现表示层和数据逻辑层的分离在观察目标和观察者之间建立一个抽象的耦合支持广播通信,简化了一对多系统设计的难度符合开闭原则,增加新的具体观察者无须修改原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便模式缺点将所有的观察者都通知到会花费很多时间如果存在循环依赖时可能导致系统崩溃没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而只是知道观察目标发生了变化使用情形一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中使它们可以各自独立地改变和复用一个对象的改变将导致一个或多个其他对象发生改变,且并不知道具体有多少对象将发生改变,也不知道这些对象是谁需要在系统中创建一个触发链
标签
Copyright ? 2015-2022 青年粮油网版权所有 备案号:皖ICP备2022009963号-20 联系邮箱:39 60 291 42@qq.com