一、观察者模式:定义了一种一对多的关系,让多个观察者对象同事监听某一个主题对象。当这个主题发生变化时,会通知所有的观察者对象,使他们自动更新自己。
二、代码示例
public interface Subject { void add(Observer observer); void remove(Observer observer); void notice(); } @Data public class ConcreteSubject implements Subject { private String subjectState; private List<Observer> observers = new ArrayList<>(); public void add(Observer observer){ observers.add(observer); } public void remove(Observer observer){ observers.remove(observer); } public void notice(){ observers.forEach(observer -> observer.update(subjectState)); } } public interface Observer { void update(String observerState); } @Data public class ConcreteObserver implements Observer { private String name; private Subject subject; public ConcreteObserver(String name, Subject subject) { this.name = name; this.subject = subject; } @Override public void update(String observerState) { System.out.println("观察者" + name + "的新状态是:" + observerState); } } public class Test { public static void main(String[] args) { ConcreteSubject s = new ConcreteSubject(); s.add(new ConcreteObserver("小明", s)); s.add(new ConcreteObserver("小红", s)); // s.remove(new ConcreteObserver("小红", s)); s.setSubjectState("123"); s.notice(); } /** result * 观察者小明的新状态是:123 * 观察者小红的新状态是:123 */ }
三、优点
1.当一个对象改变的同时需要改变其他对象,并且不知道有多少对象要改变时,应该用观察者模式
2.观察者模式其实就是解除耦合,让耦合双方都依赖于抽象,而不是依赖于具体。从而使各自的变化都不会影响另一边。
四、缺点
通知者和观察者虽然是依赖抽象,但还是有依赖,如果如果观察者和通知者根本互相就不知道,那就完美了。
解决上述缺点,可用委托
委托:是一种引用方法的类型,一旦为委托分配了方法委托将与该方法具有完全相同的行为。委托对象所搭载的方法并不需要属于同一个类。委托所搭载的方法必须与委托对象的方法具有相同的原形和形式。
代码示例
public interface Subject { void notice(String subjectState) throws Exception; } @Data public class NBAObserver { private String name; private Subject subject; public NBAObserver(String name, Subject subject) { this.name = name; this.subject = subject; } public void closeNBADirectSeeding(String subjectState){ System.out.println(subjectState + "," + name + "关闭NBA直播,继续工作!"); } } @Data public class StockObserver { private String name; private Subject subject; public StockObserver(String name, Subject subject) { this.name = name; this.subject = subject; } public void closeStockMarket(String subjectState){ System.out.println(subjectState + "," + name + "关闭股市行情,继续工作!"); } } @Data public class EventHandler { StockObserver stockObserver; NBAObserver nbaObserver; public void notice(String subjectState) { if (stockObserver != null) { stockObserver.closeStockMarket(subjectState); } if (nbaObserver != null) { nbaObserver.closeNBADirectSeeding(subjectState); } } } @Data public class Boss implements Subject { public EventHandler eventHandler; public Boss(EventHandler eventHandler) { this.eventHandler = eventHandler; } @Override public void notice(String subjectState) { eventHandler.notice(subjectState); } } @Data public class Secretary implements Subject { public EventHandler eventHandler; public Secretary(EventHandler eventHandler) { this.eventHandler = eventHandler; } @Override public void notice(String subjectState) { eventHandler.notice(subjectState); } } public class Test { public static void main(String[] args) { EventHandler eventHandler = new EventHandler(); Boss huhansan = new Boss(eventHandler); eventHandler.setStockObserver(new StockObserver("小明",huhansan)); eventHandler.setNbaObserver(new NBAObserver("小黑",huhansan)); huhansan.notice("我胡汉三回来了"); System.out.println("============================"); Secretary secretary = new Secretary(eventHandler); eventHandler.setStockObserver(new StockObserver("小明",secretary)); eventHandler.setNbaObserver(new NBAObserver("小黑",secretary)); secretary.notice("老板胡汉三回来了"); } }
优点:可实现发送者和观察的彻底解耦。