观察者模式又称为发布/订阅(Publish/Subscribe)模式。java
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知全部观察者对象,使它们可以自动更新本身。编程
Observerable:被观察者接口,规定了几个方法,分别是registerObserver():表示将观察者注册到被观察者中,即“订阅”;removeObserver():表示将观察者从被观察者中移除,即“取消订阅”;notifyObservers():当被观察者状态改变的时候,这个方法被调用,通知全部已经注册的观察者。ide
ConcreteObserverable:被观察者,实现了Observerable接口,对以上的三个方法进行了具体实现,同时有一个List集合,用以保存注册的观察者,等须要通知观察者时,遍历该集合便可。注意,该集合的泛型参数应该是Observer,接口类型,而不该该是具体的Observer实现类,这样作的缘由是一个被观察者可能会有多个不一样实现类的观察者(但都实现了Observer接口),若是限定了某一个具体的类型,那么会致使之后要加入新类型的时候而不得不修改当前类,耦合度太高,这是一个很是很差的行为。(设计原则:面向接口编程而不是面向实现编程)。this
Observer:观察者接口,规定了update()方法,当被观察者调用notifyObservers()方法时,观察者的update()方法会被回调。spa
ConcreteObserver:观察者,实现了update()方法。设计
//定义被观察者 public interface Observerable { void registerObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(); } //定义观察者 public interface Observer { public void update(int edition, float cost); } public class MagazineData implements Observerable { private List<Observer> observerList; private int edition; private float cost; public MagazineData(){ observerList = new ArrayList<>(); } @Override public void registerObserver(Observer observer) { observerList.add(observer); } @Override public void removeObserver(Observer observer) { int i = observerList.indexOf(observer); if(i >=0){ observerList.remove(i); } } @Override public void notifyObservers() { observerList.stream().forEach(item ->{ item.update(edition, cost); }); } public void setInfomation(int edition, float cost){ this.edition = edition; this.cost = cost; notifyObservers(); } } public class Customer implements Observer{ private String name; private int edition; private float cost; public Customer(String name){ this.name = name; } @Override public void update(int edition, float cost) { this.edition = edition; this.cost = cost; buy(); } public void buy(){ System.out.println(name+"购买了第"+edition+"期的杂志,花费了"+cost+"元。"); } } public static void main(String[] args) { MagazineData magazineData = new MagazineData(); Observer customerA = new Customer("A"); Observer customerB = new Customer("B"); Observer customerC = new Customer("C"); magazineData.registerObserver(customerA); magazineData.registerObserver(customerB); magazineData.registerObserver(customerC); magazineData.setInfomation(5, 20); }
推模型:被观察者主动向观察者推送自身的信息,能够是所有信息或者是部分信息。3d
拉模型:被观察者经过把自身的引用传递给观察者,须要观察者自行经过该引用来获取相关的信息。code
好比咱们有两个对象,一个对象依赖于另外一个对象的变化而变化,此时咱们能够将这两个对象抽象出来,作成接口,利用观察者模式来进行解耦,又或者,当一个对象发生变化的时候,须要通知别的对象来作出改变,但又不知道这样的对象有多少个,此时利用观察者模式很是合适。server
参考例子对象