首页 > 代码库 > 观察者模式
观察者模式
概述:
观察者模式主要用于1:N的通知,当一个对象(目标对象)的状态改变时,他需要及时告知其他一系列对象(观察者),令他们做出相应的响应。
观察者模式有两种形式,推和拉。这里用电台广播做例子。
使用场景:
1、关联行为场景,需要注意的是,关联行为是可拆分的,而不是“组合”关系
2、事件多级触发场景
观察者的角色:
1、抽象被观察者:提供一个接口,可以新增、删除、通知观察者
2、具体被观察者:具体主题改变时,将对于信息发送给观察者
3、抽象观察者:定义一个更新的接口,以便接受被观察者的信息
4、具体观察者:实现抽象观察者,获取被观察者的信息。
一、推模式:每次都会把通知以广播方式发生给所有观察者,所有观察者只能被动接受。
1、定义听众抽象类(抽象观察者):
public interface Audience { //接收信息 public void receiveInfo(String message); }
2、定义具体听众(具体观察者):这里分别定义一个喜欢旅游者和程序猿
public class Tourist implements Audience{ //旅游者 private String name; public Tourist(String name){ this.name = name; } @Override public void receiveInfo(String message) { System.out.println(name+":"+message); } } public class Programmer implements Audience { //程序猿 private String name; public Programmer(String name){ this.name = name; } @Override public void receiveInfo(String message) { System.out.println(name+":"+message); } }
3、定义一个抽象被观察者
public interface Subject { //添加观察者 public void addAudience(Audience audience); //删除观察者 public void delAudience(Audience audience); //通知观察者 public void notifyAudience(String message); }
4、定义一个被观察者(电台):
public class RadioSation implements Subject { List<Audience> audienceList = new ArrayList<Audience>(); //通知观察者 @Override public void addAudience(Audience audience) { audienceList.add(audience); } //删除观察者 @Override public void delAudience(Audience audience) { audienceList.remove(audience); } @Override public void notifyAudience(String message) { for(Audience audience:audienceList){ audience.receiveInfo(message); } } }
这样观察者模式已经实现,我们模拟电台发送信息
public class ObservationClient { public static void main(String[] args) { //定义观察者 Audience programmer = new Programmer("程序员"); Audience tourist = new Tourist("游者"); //定义被观察者(电台) Subject radioSation = new RadioSation(); radioSation.addAudience(programmer); radioSation.addAudience(tourist); radioSation.notifyAudience("华山免费两日游"); } }
执行结果:
从上面的例子可以看出,电台听众可以接受到电台的信息,当只能被动的接收,这些信息可能是听众不需要的(程序员不想知道旅游信息)。如果我们要实现听众可以自主的选择要接受的内容,就需要使用拉模式。
二、拉模式:观察者只要知道情况即可,至于什么时候获取内容,获取什么内容,都可以自主决定(把这个被观察者的信息扔个观察者)
1、定义一个抽象被观察者(修改notifyAudience方法,添加发布信息)
public interface Subject { //添加观察者 public void addAudience(Audience audience); //删除观察者 public void delAudience(Audience audience); //发布信息(分别是旅游信息、it信息) public void releaseInfo(String touristInformation,String itInformation); //通知观察者 public void notifyAudience(); }
2、定义被观察者(电台),分别定义获取it信息和旅游信息,是为了让观察者选择自己喜欢信息
public class RadioSation implements Subject { List<Audience> audienceList = new ArrayList<Audience>(); private String touristInformation; //旅游信息 private String itInformation; //it信息 //通知观察者 @Override public void addAudience(Audience audience) { audienceList.add(audience); } //删除观察者 @Override public void delAudience(Audience audience) { audienceList.remove(audience); } //发布信息 @Override public void releaseInfo(String touristInformation, String itInformation) { this.setTouristInformation(touristInformation); this.setItInformation(itInformation); } @Override public void notifyAudience() { for(Audience audience:audienceList){ audience.receiveInfo(this); } } public String getTouristInformation() { return touristInformation; } public void setTouristInformation(String touristInformation) { this.touristInformation = touristInformation; } public String getItInformation() { return itInformation; } public void setItInformation(String itInformation) { this.itInformation = itInformation; } }
3、定义听众抽象类(抽象观察者):
public interface Audience { //接收信息(接受整个电台) public void receiveInfo(Subject subject); }
4、定义具体听众(具体观察者):这里分别定义一个喜欢旅游者和程序猿
public class Tourist implements Audience{ //旅游者 private String name; public Tourist(String name){ this.name = name; } @Override public void receiveInfo(Subject subject) { //获取旅游方面的信息 System.out.println(name+":"+((RadioSation)subject).getTouristInformation()); } } public class Programmer implements Audience { //程序猿 private String name; public Programmer(String name){ this.name = name; } @Override public void receiveInfo(Subject subject) { //获取it方面的信息 System.out.println(name+":"+((RadioSation)subject).getItInformation()); } }
模拟电台发送信息:
public class ObservationClient { public static void main(String[] args) { //定义观察者 Audience programmer = new Programmer("程序员"); Audience tourist = new Tourist("游者"); //定义被观察者(电台) Subject radioSation = new RadioSation(); radioSation.addAudience(programmer); radioSation.addAudience(tourist); //发布信息 radioSation.releaseInfo("华山两天免费游","jdk已经出8了"); radioSation.notifyAudience(); } }
输出结果:
这样就实现了,具体观众获取自己想要的电台信息。
O(∩_∩)O Done!
观察者模式