精通23种设计模式——观察者模式
来源:互联网 发布:.net core 2.0 数据库 编辑:程序博客网 时间:2024/06/09 21:39
观察者模式
以NBA球星和媒体之间的关系为例,球星的一举一动都在媒体的关注之下,比如,球星去夜店做了什么什么事情,媒体都会第一时间给出报导。
那么这里球星就属于被观察者,媒体属于观察者。
需要定义一个球员接口,包含球员可能出现的各种情况:
public interface BasketballPlayer { /** * 球员去夜店 */ public void goNightclub(); /** * 球员发推特 */ public void publishTwitter();}
其次需要定义一个新闻媒体的接口,每当球员有新的情况,就会更新消息:
public interface NewsMedia { public void update(String message);}
我们以哈登去夜店,发推特为例,其中还需要为哈登单独定义两个flag变量,是不是去夜店啦,是不是发推特啦,以及他们对应的get,set方法。
public class Harden implements BasketballPlayer{ private boolean isGoNightclub = false; private boolean isPublishTwitter = false; /** * 哈登去夜店了 */ public void goNightclub() { setGoNightclub(true); } /** * 哈登发推特了 */ public void publishTwitter() { setPublishTwitter(true); } public boolean isGoNightclub(){ return isGoNightclub; } public void setGoNightclub(boolean isGoNightclub){ this.isGoNightclub = isGoNightclub; } public boolean isPublishTwitter(){ return isPublishTwitter; } public void setPublishTwitter(boolean isPublishTwitter){ this.isPublishTwitter = isPublishTwitter; }}
新闻媒体以ESPN为例:
public class ESPN implements NewsMedia{ public void update(String type) { System.out.println(type); }}
ESPN肯定不会一天24小时都花在哈登身上,于是,ESPN雇了一名记者Jack,全程跟踪报道哈登,一有消息就通知ESPN。
public interface Journalist extends Runnable{}/** * Created by lovekun on 2016/10/21. * */public class Jack implements Journalist, Runnable{ private BasketballPlayer mBasketballPlayer; private NewsMedia mNewsMedia; private String mType; /** * * @param basketballPlayer * @param newsMedia * @param type 监控内容 */ public Jack(BasketballPlayer basketballPlayer, NewsMedia newsMedia, String type){ this.mBasketballPlayer = basketballPlayer; this.mNewsMedia = newsMedia; this.mType = type; } public void run() { while (true){ synchronized (mBasketballPlayer){ if (mType.equals("Nightclub")){ if (((Harden)mBasketballPlayer).isGoNightclub()){ mNewsMedia.update("哈登去夜店了"); ((Harden) mBasketballPlayer).setGoNightclub(false); } }else if(mType.equals("publishTwitter")){ if (((Harden)mBasketballPlayer).isPublishTwitter()){ mNewsMedia.update("哈登发推特了"); ((Harden) mBasketballPlayer).setPublishTwitter(false); } } } } }}
这里需要注意更新哈登信息和状态,需要放在同步代码块中,以防哈登离开一家夜店后,Jack还没有来及更新它的状态,哈登又进了另一家夜店,导致Jack无法及时更新信息和通知ESPN。
剩下的就是场景类了:
/** * Created by lovekun on 2016/10/21. * * 观察者模式场景类 */public class ObserverClient { public static void main(String[] args) throws Exception{ BasketballPlayer mBasketballPlayer = new Harden(); NewsMedia mESPN = new ESPN(); Journalist journalistForNightclub = new Jack(mBasketballPlayer, mESPN, "Nightclub"); Thread threadForNightclub = new Thread(journalistForNightclub); threadForNightclub.start(); Journalist journalistForPublishTwitter = new Jack(mBasketballPlayer, mESPN, "publishTwitter"); Thread threadForPublishTwitter = new Thread(journalistForPublishTwitter); threadForPublishTwitter.start(); Thread.sleep(2000); mBasketballPlayer.goNightclub(); Thread.sleep(2000); mBasketballPlayer.goNightclub(); Thread.sleep(2000); mBasketballPlayer.publishTwitter(); Thread.sleep(2000); mBasketballPlayer.goNightclub(); }}
这种方法通过一个线程里的死循环不断监听,如果监听的东西多了,会导致系统的性能极差。
既然球员一有动作,新闻媒体就会知道,可以把新闻媒体聚合到球员类中。
仍然定义一个球员接口和新闻媒体接口
/** * Created by lovekun on 2016/10/21. */public interface BasketballPlayer { /** * 球员去夜店 */ public void goNightclub(); /** * 球员发推特 */ public void publishTwitter();}
/** * Created by lovekun on 2016/10/21. */public interface NewsMedia { public void update(String message);}
实现一个被观察者的接口,包含对观察者的添加,删除,通知方法。
/** * Created by lovekun on 2016/10/21. */public interface Observable { public void addObserver(NewsMedia newsMedia); public void delObserver(NewsMedia newsMedia); public void notifyObservers(String message);}
实例如一个巨星哈登,他实现了球员接口,同时也是一个被观察者,实现了被观察者接口:
/** * Created by lovekun on 2016/10/21. */public class Harden implements BasketballPlayer, Observable{ private ArrayList<NewsMedia> newsMedias = new ArrayList<NewsMedia>(); /** * 哈登去夜店了 */ public void goNightclub() { notifyObservers("哈登去夜店了"); } /** * 哈登发推特了 */ public void publishTwitter() { notifyObservers("哈登发推特了"); } public void addObserver(NewsMedia newsMedia) { this.newsMedias.add(newsMedia); } public void delObserver(NewsMedia newsMedia) { this.newsMedias.remove(newsMedia); } public void notifyObservers(String message) { for (NewsMedia newsMedia : newsMedias){ newsMedia.update(message); } }}
关注哈登的媒体有很多,ESPN、腾讯等等
/** * Created by lovekun on 2016/10/21. */public class ESPN implements NewsMedia { public void update(String message) { System.out.println("ESPN新闻:" + message); }}
/** * Created by lovekun on 2016/10/21. */public class Tengxun implements NewsMedia{ public void update(String message) { System.out.println("腾讯新闻:" + message); }}
剩下的就是场景类的实现:
/** * Created by lovekun on 2016/10/21. * * 观察者模式场景类 */public class ObserverClient { public static void main(String[] args) throws Exception{ BasketballPlayer harden = new Harden(); ((Harden) harden).addObserver(new ESPN()); ((Harden) harden).addObserver(new Tengxun()); harden.goNightclub(); harden.publishTwitter(); }}
这样,如果还有虎扑,新浪等媒体也关注哈登,这些新闻媒体只需要实现NewMedia接口,并且harden的实例添加这些观察者即可。程序具有了更好的可扩展性。
- 参考内容: 《涉及模式之禅》
- 源码下载: 观察者模式源码
0 0
- 精通23种设计模式——观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者
- 23种设计模式之——观察者模式
- 精通23种设计模式——代理模式
- 精通23种设计模式——单例模式
- 精通23种设计模式——工厂方法模式
- 精通23种设计模式——责任链模式
- 设计模式——观察者设计模式
- 设计模式——观察者
- Math 类
- 浮水法
- SSH学习之Hibernate的配置文件
- 山寨美图秀秀的美肤功能----实现过程
- uboot下init_sequence_f函数之reserve_malloc
- 精通23种设计模式——观察者模式
- 用两个栈实现队列
- Random类
- GreenDao的使用
- IBM MB(IIB)访问数据库的消息流开发示例
- 计算机运行快捷键
- struts2中使用validate校验数据
- Java 并发开发:Lock 框架详解
- C语言二进制文件读取