观察者模式:某些事件发生时(比如状态转变),如果一个对象(通常我们称之为主题)需要自动地通知其他多个对象(称为观察者)
例子:实现一个定制化的通知系统。有好几家报纸机构,比如《纽约时报》《卫报》以及《世界报》都订阅了新闻中心,他们希望当接收的新闻中包含他们感兴趣的关键字时,能得到特别通知。
1、java传统实现:
步骤 1
提供给观察者们一个接口,使观察者可以自定义实现自己的订阅策略(自己感兴趣的关键字)。
Observer.java
interface Observer { void notify(String tweet); }
步骤 2
观察者们各自实现接口
NYTimes.java
Guardian.java
LeMonde.java
class NYTimes implements Observer{ public void notify(String tweet) { if(tweet != null && tweet.contains("money")){ System.out.println("Breaking news in NY! " + tweet); } } } class Guardian implements Observer{ public void notify(String tweet) { if(tweet != null && tweet.contains("queen")){ System.out.println("Yet another news in London... " + tweet); } } } class LeMonde implements Observer{ public void notify(String tweet) { if(tweet != null && tweet.contains("wine")){ System.out.println("Today cheese, wine and news! " + tweet); } } }
步骤 3
定义一个新闻中心的接口Subject,有两个方法,registerObserver方法注册一个新的观察者,notifyObservers方法通知它的观察者一个新闻的到来
Subject.java
interface Subject{ void registerObserver(Observer o); void notifyObservers(String tweet); }
步骤 4
实现新闻中心的接口Subject,定义新闻中心类。
Feed.java
class Feed implements Subject{ private final List<Observer> observers = new ArrayList<>(); public void registerObserver(Observer o) { this.observers.add(o); } public void notifyObservers(String tweet) { observers.forEach(o -> o.notify(tweet)); } }
步骤 5
一条新闻到达时,它就进行通知。
Feed f = new Feed(); f.registerObserver(new NYTimes()); f.registerObserver(new Guardian()); f.registerObserver(new LeMonde()); f.notifyObservers("The queen said her favourite book is Java 8 in Action!");
2、Java8实现:
使用Lambda表达式后,你无需显式地实例化三个观察者对象,直接传递Lambda表达式表示需要执行的行为即可。f.registerObserver((String tweet) -> { if(tweet != null && tweet.contains("money")){ System.out.println("Breaking news in NY! " + tweet); } }); f.registerObserver((String tweet) -> { if(tweet != null && tweet.contains("queen")){ System.out.println("Yet another news in London... " + tweet); } });