设计模式-观察者模式
1.什么是观察者模式
观察者模式(Observer Pattern)又称为发布/订阅模式, 属于行为型模式。
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
自己理解 一个事情随着另一件事情发生变化 , 两个事情存在内在联系 ,一个是观察者 , 另一个是被观察者。
2.为什么要用观察者模式
一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知,而不用一个个的进行通知,达到对象依赖关系弱化。
3.怎么用观察者模式
例子1
用户收到人民日报公众号发布房价上涨的消息的不同反应
被观察者 人民日报公众号
观察者 用户
public class ObserverPatternTest { public static void main(String[] args) { //开始运营订阅号 WeChatSubscribe subject = new PeopleDaily(); //用户都已经注册 AbstractUser obs1 = new ZhangSan(); AbstractUser obs2 = new LiSi(); //用户陆续关注 subject.add(obs1); subject.add(obs2); //通知已经关注的用户 subject.notifyObserver(); } } /*** *功能描述 观察者-----------抽象观察者 */ abstract class AbstractUser { /*** * 抽象反应,每个人反应不一样,有的吃惊,有的高兴 */ abstract void response(); } /*** *功能描述 观察者-----------具体观察者---张三 */ class ZhangSan extends AbstractUser { @Override public void response() { System.out.println("张三作为具体观察者,听了很伤心"); } } /*** *功能描述 被观察者-----------具体观察者---李四 */ class LiSi extends AbstractUser { @Override public void response() { System.out.println("李四作为具体观察者,听了很高兴"); } } /*** *功能描述 被观察者-----------抽象目标,微信订阅号 */ abstract class WeChatSubscribe { /*** * 定义观察者集合,用于增加、删除订阅者(观察者),可被覆写延迟到子类中实现 */ protected List<AbstractUser> observers = new ArrayList<AbstractUser>(); /*** * 增加观察者方法,可进行抽象,延迟到子类中实现 */ public void add(AbstractUser observer) { observers.add(observer); } /*** * 删除观察者方法,可进行抽象,延迟到子类中实现 */ public void remove(AbstractUser observer) { observers.remove(observer); } /*** * 通知观察者方法 */ public abstract void notifyObserver(); } /*** *功能描述 被观察者-----------具体目标 人民日报是具体目标 */ class PeopleDaily extends WeChatSubscribe { @Override public void notifyObserver() { System.out.println("具体目标发生改变..."); System.out.println("人民日报发送了房价上涨的消息..."); System.out.println("--------------"); for (AbstractUser users : observers) { users.response(); } } }
结果如下
例子2
用户收到微信服务号的推送消息,若取消关注就收不到推送
被观察者 微信公众号
观察者 用户
public class ObserverPatternTest2 { public static void main(String[] args) { WechatServer server = new WechatServer(); Observer userZhang = new User("ZhangSan"); Observer userLi = new User("LiSi"); Observer userWang = new User("WangWu"); server.registerObserver(userZhang); server.registerObserver(userLi); server.registerObserver(userWang); server.setInfomation("第一次推送!"); System.out.println("----------------------------------------------"); server.removeObserver(userZhang); server.setInfomation("第二次推送!"); } } /** *功能描述 观察者接口 */ interface Observer { /** * */ public void update(String message); } /** * 功能描述 观察者接口子类 */ class User implements Observer { private String name; private String message; public User(String name) { this.name = name; } @Override public void update(String message) { this.message = message; read(); } public void read() { System.out.println(name + " 收到推送消息: " + message); } } /** * 功能描述 被观察者接口 */ interface Observerable { /** * 注册观察者 */ public void registerObserver(Observer o); /** * 删除观察者 */ public void removeObserver(Observer o); /** * 通知观察者 */ public void notifyObserver(); } /** * 功能描述 被观察者子类 */ class WechatServer implements Observerable { /*** * 注意到这个List集合的泛型参数为Observer接口,设计原则:面向接口编程而不是面向实现编程 */ private List<Observer> list; private String message; public WechatServer() { list = new ArrayList<Observer>(); } @Override public void registerObserver(Observer o) { list.add(o); } @Override public void removeObserver(Observer o) { if (!list.isEmpty()) { list.remove(o); } } @Override public void notifyObserver() { for (int i = 0; i < list.size(); i++) { Observer oserver = list.get(i); oserver.update(message); } } public void setInfomation(String s) { this.message = s; System.out.println("微信服务更新消息: " + s); //消息更新,通知所有观察者 notifyObserver(); } }
结果如下
例子3
多方和空方收到原油期货上涨下跌不同反应
被观察者 原油期货
观察者 多方和空方
public class CrudeOilFutures { public static void main(String[] args) { OilFutures oil = new OilFutures(); //多方 Observer bull = new Bull(); //空方 Observer bear = new Bear(); oil.addObserver(bull); oil.addObserver(bear); oil.setPrice(10); oil.setPrice(-8); } } /*** *功能描述 被观察者----具体目标类:原油期货 */ class OilFutures extends Observable { private float price; public float getPrice() { return this.price; } public void setPrice(float price) { //设置内部标志位,注明数据发生变化 super.setChanged(); //通知观察者价格改变了 super.notifyObservers(price); this.price = price; } } /*** *功能描述 观察者----具体观察者类:多方 */ class Bull implements Observer { @Override public void update(Observable o, Object arg) { Float price = ((Float) arg).floatValue(); if (price > 0) { System.out.println("油价上涨" + price + "元,多方高兴了!"); } else { System.out.println("油价下跌" + (-price) + "元,多方伤心了!"); } } } /*** *功能描述 观察者----具体观察者类:空方 */ class Bear implements Observer { @Override public void update(Observable o, Object arg) { Float price = ((Float) arg).floatValue(); if (price > 0) { System.out.println("油价上涨" + price + "元,空方伤心了!"); } else { System.out.println("油价下跌" + (-price) + "元,空方高兴了!"); } } }
结果如下
古人学问无遗力,少壮工夫老始成。
纸上得来终觉浅,绝知此事要躬行。