观察者模式,属于行为型设计模式的一种。在该模式下当某个对象发生变化时,会自动通知所有关心该对象的其它对象。避免了其它对象使用轮询这一低效的方式来检查该对象是否发生变化
模式思想
自媒体时代下,写微信公众号的人已经越来越多了。当微信用户关注公众号后,一旦公众号更新文章,关注该公众号的用户即会自动收到其文章消息的推送,而不需要用户时时刻刻主动查看该公众号是否更新了文章。这个例子就很好的体现了我们今天要介绍的设计模式——观察者模式的思想。在该模式下,通常会有多个观察者监听、关注某个主题对象,在主题对象发生变化、更新时,相应的观察者对象会自动收到相应的消息。该模式下通常有四个角色
- 抽象主题角色:其声明了各具体主题角色的通用方法,包括添加、移除、通知观察者等方法。即本文的WechatOfficialAccount微信公众号类
- 具体主题角色:其是对抽象主题角色的具体实现,通常其内部会有一个容器用于对观察者实例进行管理。即本文一个名为ProjectDaedalus的微信公众号类
- 抽象观察者角色:其声明了各具体观察者角色的通用方法,通常其会定义一个update方法,用于在主题角色发生变化、更新时通知自己。即本文的Observer类
- 具体观察者角色:其是观察者的具体实现类。其实现了update方法,当主题角色发生变化、更新时,即可通过该方法获取更新。即本文的WechatUser微信用户类
实现
现在我们利用Java来实现上文提到的公众号的例子。首先实现抽象主题角色、具体主题角色——即WechatOfficialAccount、ProjectDaedalus类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
public interface WechatOfficialAccount {
void attach(Observer observer);
void detach(Observer observer);
void notify(String message);
} ...
public class ProjectDaedalus implements WechatOfficialAccount{
private List<Observer> observerList = new LinkedList<>();
private final String name = "ProjectDaedalus";
@Override public void attach(Observer observer) { observerList.add(observer); }
@Override public void detach(Observer observer) { observerList.remove(observer); }
@Override public void notify(String message) { for(Observer observer : observerList) { observer.update(name, message); } } }
|
然后,来实现所谓的观察者,即Observer、WechatUser类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
public interface Observer {
void update(String name, String message); } ...
public class WechatUser implements Observer {
private String username;
public WechatUser(String username) { this.username = username; }
@Override public void update(String name, String message) { String str = "<" + username + ">: 收到公众号[" + name + "]推送的文章, 内容如下:"; System.out.println( str ); System.out.println( message ); } }
|
现在,让我们看看该模式如何运作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
public class ObserverPatternDemo { public static void main(String[] args) { WechatOfficialAccount wechatOfficialAccount = new ProjectDaedalus();
WechatUser user1 = new WechatUser("小明"); WechatUser user2 = new WechatUser("小红"); WechatUser user3 = new WechatUser("小王");
wechatOfficialAccount.attach(user1); wechatOfficialAccount.attach(user2); wechatOfficialAccount.attach(user3);
System.out.println("---------------------- Test 1 ----------------------"); String msg1 = "关于积极推进新形势下阶级斗争的相关通知, ..."; wechatOfficialAccount.notify(msg1);
System.out.println("\n---------------------- Test 2 ----------------------"); wechatOfficialAccount.detach(user3); String msg2 = "关于恢复以经济建设为中心等若干重大问题的决定, ..."; wechatOfficialAccount.notify(msg2); } }
|
测试结果如下,符合预期
参考文献
- Head First 设计模式 弗里曼著