观察者模式原理
当一个对象改变了自身的状态后,它会通知其他对象告知发生了变化。
用设计模式的语言来说,改变自身状态的对象叫做主题(Subject),接受改变通知的那些对象叫做观察者。其关系是一对多的,一个主题可以有多个观察者。
观察者类图
观察者模式引入了一个Observer接口,所有具体的观察者都需要实现该接口。该接口只有一个方法,主题会调用该方法,通知观察者自己的状态发生了变化。每个主题都持有一个已注册的观察者列表,并且会调用一个方法(notifyObservers)来通知注册的观察者关于主题的更新或是变化。主题提供了注册和取消注册观察者的方法。
使用普通方法实现观察者模式
Java对观察者模式提供了开箱即用的实现。通过实现Observer接口,以及继承Observable类,可以轻松实现观察者模式。
用观察者模式做一个新闻订阅的功能,当新闻发生改变的时候,通知所有订阅者有新的新闻。
定义主题:
1 import java.util.ArrayList; 2 import java.util.List; 3 import java.util.Observable; 4 import java.util.Observer; 5 6 /** 7 * @author jiashubing 8 * @since 2017/7/17 9 */ 10 public class NewsAgency extends Observable implements Publisher { 11 private List<Observer> channels = new ArrayList<>(); 12 13 public void addNews(String newsItem){ 14 notifyObservers(newsItem); 15 } 16 17 public void notifyObservers(String newsItem){ 18 for(Observer outlet : this.channels){ 19 outlet.update(this, newsItem); 20 } 21 } 22 23 public void register(Observer outlet){ 24 channels.add(outlet); 25 } 26 }
Publisher接口:
public interface Publisher { }
具体的观察者:
1 import java.util.Observable; 2 import java.util.Observer; 3 4 /** 5 * @author jiashubing 6 * @since 2017/7/17 7 */ 8 public class RadioChannel implements Observer { 9 10 @Override 11 public void update(Observable agency, Object newsItem){ 12 if(agency instanceof Publisher){ 13 System.out.println((String)newsItem); 14 } 15 } 16 }
测试:
1 public class Test { 2 public static void main(String[] args){ 3 //创建主题 4 NewsAgency newsAgency = new NewsAgency(); 5 6 //创建观察者 7 RadioChannel radioChannel1 = new RadioChannel(); 8 RadioChannel radioChannel2 = new RadioChannel(); 9 10 //主题注册观察者 11 newsAgency.register(radioChannel1); 12 newsAgency.register(radioChannel2); 13 14 newsAgency.addNews("第一条新闻"); 15 newsAgency.addNews("第二条新闻"); 16 newsAgency.addNews("第三条新闻"); 17 } 18 }
输出结果为:
第一条新闻
第一条新闻
第二条新闻
第二条新闻
第三条新闻
第三条新闻
其中Observer 接口的内容是:
public interface Observer { void update(Observable o, Object arg); }
Observable类的代码就比较多了。
参考《Professional Java EE Design Patterns》
原创文章,欢迎转载,转载请注明出处!