观察者模式,用通俗易懂的话来理解就是,在一个对象的改变会改变其他很多的对象,而且还不知道会改变多少个其他对象的时候,就该要考虑观察者模式了
其实观察者模式在的主要工作就是解除双方的耦合度,让两端不依赖具体细节,而去依赖于抽象,所以其中一方的改变,会去更新到其他的N多方
以下就举三个例子来说明,看完三个例子后,你会发现观察者模式把(依赖倒置原则)表现出来了
案例一:(服务器更新手机)
更新全国所有的QQ,有很多手机种类 ,例如(小米,魅族,步步高,三星,等等…. 省略)
/** * 通知主题更新的抽象类 * @author Liudeli * */ public abstract class Service { /** * 增加我要通知者,这里存入的是抽象(抽象包括抽象类或) * @param iPhone */ public abstract void add(IPhone iPhone); /** * 发出更新消息给各个手机 */ public abstract void sendUpdateMsg(); }
package com.oop.demo5; import java.util.ArrayList; import java.util.List; /** * 华为服务器对象 * @author Liudeli * */ public class HUAWEIService extends Service { private List<IPhone> listPhone = new ArrayList<IPhone>(); @Override public void add(IPhone iPhone) { listPhone.add(iPhone); } @Override public void sendUpdateMsg() { for (IPhone iphone : listPhone) { iphone.update(); } } }
package com.oop.demo5; import java.util.ArrayList; import java.util.List; /** * 戴尔服务器对象 * @author Liudeli * */ public class DELLService extends Service { private List<IPhone> listPhone = new ArrayList<IPhone>(); @Override public void add(IPhone iPhone) { listPhone.add(iPhone); } @Override public void sendUpdateMsg() { for (IPhone iphone : listPhone) { iphone.update(); } } }
package com.oop.demo5; /** * 更新手机的规范 * @author Liudeli * */ public interface IPhone { /** * 更新所有手机的行为标准规范 */ public void update(); }
package com.oop.demo5; /** * 魅族手机对象 * @author Liudeli * */ public class MeizuPhone implements IPhone { public void update() { System.out.println("魅族手机需要去更新QQ了哦..."); } }
package com.oop.demo5; /** * 小米手机对象 * @author Liudeli * */ public class MIPhone implements IPhone { public void update() { System.out.println("小米手机更新QQ了..."); } }
package com.oop.demo5; /** * 三星手机对象 * @author Liudeli * */ public class SamsungPhone implements IPhone { public void update() { System.out.println("三星手机该更新QQ啦..."); } }
package com.oop.demo5; /** * 步步高手机对象 * @author Liudeli * */ public class VivoPhone implements IPhone { public void update() { System.out.println("步步高手机需要去更新手机QQ了哦..."); } }
/** * 测试端程序 * @author Liudeli * */ public class Main { public static void main(String[] args) { // 使用戴尔服务器,来更新手机QQ Service service = new DELLService(); // 增加观察者(增加需要更新的手机对象) service.add(new MIPhone()); service.add(new MeizuPhone()); service.add(new SamsungPhone()); service.add(new VivoPhone()); // 给手机发出通知 service.sendUpdateMsg(); System.out.println("省略..."); } }
运行结果:
如果某天,戴尔服务器出问题了,自动切换到备用服务器 华为服务器:
// 使用华为服务器,来更新手机QQ Service service = new HUAWEIService();
案例二:(通知同事)
package com.oop.demo3; /** * 定义观察者抽象类 * @author Liudeli * */ public abstract class Observer { private String name; private ISecretary secretary; public Observer(String name, ISecretary secretary) { this.name = name; this.secretary = secretary; } /** * 更新 */ public abstract void update(); }
package com.oop.demo3; /** * 不能依赖细节,细节应该依赖抽象,老板,和秘书,和其他秘书都是细节,抽象则是这些细节所定义的规范 * @author Liudeli * */ public interface ISecretary { /** * 增加 * @param stockObserver */ public void add(Observer observer); /** * 通知 */ public void notice(); /** * 前台状态 */ public String getAction(); public void setAction(String action); }
package com.oop.demo3; /** * 定义股票观察员对象 * @author Liudeli * */ public class StockObserver extends Observer{ private String name; private ISecretary secretary; public StockObserver(String name, ISecretary secretary) { super(name, secretary); this.name = name; this.secretary = secretary; } @Override public void update() { System.out.println(secretary.getAction() + name + " 请你关闭股票行情,继续工作"); } }
package com.oop.demo3; /** * 定义看NBA的同事 * @author Liudeli * */ public class NBAObserver extends Observer { private String name; private ISecretary secretary; public NBAObserver(String name, ISecretary secretary) { super(name, secretary); this.name = name; this.secretary = secretary; } @Override public void update() { System.out.println(secretary.getAction() + name + " 请你关闭NBA视频画面,继续工作"); } }
package com.oop.demo3; import java.util.ArrayList; import java.util.List; /** * 前台秘书类 * @author Liudeli * */ public class Secretary implements ISecretary{ /** * 定义同事集合 */ private List<Observer> list = new ArrayList<Observer>(); /** * 增加 * @param stockObserver */ public void add(Observer observer) { list.add(observer); } /** * 通知 */ public void notice() { for (Observer observer : list) { observer.update(); } } /** * 前台状态 */ private String action; public String getAction() { return this.action; } public void setAction(String action) { this.action = action; } }
package com.oop.demo3; import java.util.ArrayList; import java.util.List; /** * 老板对象 * @author Liudeli * */ public class Boss implements ISecretary { /** * 定义同事集合(具体抽象) */ private List<Observer> list = new ArrayList<Observer>(); /** * 增加 * @param stockObserver */ public void add(Observer observer) { list.add(observer); } /** * 通知 */ public void notice() { for (Observer observer : list) { observer.update(); } } /** * 前台状态 */ private String action; public String getAction() { return this.action; } public void setAction(String action) { this.action = action; } }
package com.oop.demo3; /** * 测试程序 * @author Liudeli * */ public class Main { public static void main(String[] args) { // 前台小姐如花 ISecretary secretary = new Secretary(); // 看股票的两位同事 StockObserver stockObserver1 = new StockObserver("刘奋", secretary); StockObserver stockObserver2 = new StockObserver("刘忙", secretary); // 看NBA的一位同事 NBAObserver nbaObserver = new NBAObserver("黄流", secretary); // 如花记下两位同事 secretary.add(stockObserver1); secretary.add(stockObserver2); // 如花记下一个看NBA的同事 secretary.add(nbaObserver); // 发现老板回来了 secretary.setAction("老板回来了!"); // 通知通知,老板回来了 secretary.notice(); } }
运行结果:
简化理解:
抽象通知类
/** * 主题,抽象通知类 * @author Liudeli * */ public abstract class Subject { /** * 增加 * @param observer */ public abstract void add(Observer observer); /** * 通知观察者 */ public abstract void notice(); // 通知的内容 public abstract String getNoticeContext(); public abstract void setNoticeContext(String noticeContext); }
观察者抽象类
package com.oop.demo4; /** * 观察者抽象类 * @author Liudeli * */ public abstract class Observer { /** * 更新(具体观察者打印状态) */ public abstract void update(); }
具体通知对象:
package com.oop.demo4; import java.util.ArrayList; import java.util.List; /** * 通知的具体对象 * @author Liudeli * */ public class SubjectSpecific extends Subject { // 定义所有观察者集合 private List<Observer> list = new ArrayList<Observer>(); @Override public void add(Observer observer) { list.add(observer); } @Override public void notice() { for (Observer observer : list) { observer.update(); } } private String noticeContext; @Override public String getNoticeContext() { return noticeContext; } @Override public void setNoticeContext(String noticeContext) { this.noticeContext = noticeContext; } }
具体观察对象:
package com.oop.demo4; public class ObserverSpecific extends Observer { private Subject subject; private String name; public ObserverSpecific(Subject subject, String name) { this.subject = subject; this.name = name; } @Override public void update() { System.out.println("通知我," + name + subject.getNoticeContext() + "好好工作..."); } }
测试程序:
package com.oop.demo4; public class Main { public static void main(String[] args) { // 得到通知者 Subject subject = new SubjectSpecific(); Observer observerA = new ObserverSpecific(subject, "旺财"); Observer observerB = new ObserverSpecific(subject, "局花"); subject.add(observerA); subject.add(observerB); subject.setNoticeContext(",Boss 回来了!"); subject.notice(); } }
运行结果: