观察者模式

发布日期:2019-10-07

观察者模式:

定义对象之间一种一对多的关系,使得每当一个一个对象发生改变的时候,其相关依赖对象皆通知并且自动更改。

 

意图定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新

主要解决一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

如何解决使用面向对象技术,可以将这种依赖关系弱化。

关键代码在抽象类里有一个 ArrayList 存放观察者们。

 

 

一个对象的状态或者行为的变化,将导致对其他行为发生也发生变化,他们之间会陈胜联动

在观察者模式中,发生改变的对象称为观察目标,被通知的对象称为观察者

一个观察目标可以对应多个观察者

 

 

观察者模式又称发布-订阅模式,模型-视图模式,源-监听器模式,从属者模式

 

Subject(目标):又称为主题,是指观察者的对象,在目标中定义一个集合,可以接受任意数量的观察者,目标可以为抽象类。

ConcreteSubject(具体目标):是目标的子类,包含经常发生改变的数据,当状态改变的时候,将向观察者发出通知。

Observe(观察者):将对具体目标做出反应,一般定义为接口,该接口声明了一个更新数据的方法,又称抽象观察者。

ConcreteObserve(具体观察者):在具体观察者中维护和指向观察者目标对象的引用,它存储观察者的某些状态。

 

优点: 

1、观察者和被观察者是抽象耦合的。

2、建立一套触发机制。

缺点: 

1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。

2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

 

使用场景:

1.一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。

2.一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。

3.一个对象必须通知其他对象,而并不知道这些对象是谁。

4.需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

 

代码设计:

subject.java

public class subject { private List<Observe> observes = new ArrayList<Observe>();//添加 public void addObserve(Observe observe){ observes.add(observe); }  //通知 public void notifys(){ for (Observe o : observes){ o.update(); } }}

 

Observe.java

public abstract class Observe { protected subject subject; public abstract void update();}

 

BusObserver1.java

public class BusObserver1 extends Observe { @Override public void update() { System.out.println("看到红灯,减速停车Bus1"); } public BusObserver1(subject subject){ this.subject = subject; this.subject.addObserve(this); }}

 

BusObserver2.java

public class BusObserver2 extends Observe { @Override public void update() { System.out.println("看到红灯,减速停车Bus2"); } public BusObserver2(subject subject){ this.subject = subject; this.subject.addObserve(this); }}

 

测试:

public class test { public static void main(String[] args) { subject subject = new subject(); BusObserver1 binaryObserver = new BusObserver1(subject); BusObserver2 octalObserver = new BusObserver2(subject); System.out.println("红灯..."); subject.notifys(); }}

 

结果:

红灯...看到红灯,减速停车Bus1看到红灯,减速停车Bus2