观察者模式
Overview
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。
比如,当一个对象被修改时,则会自动通知依赖它的对象。
观察者模式属于行为型模式。
主要解决
一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用
一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
应用实例
拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价
优点
实现一
Observer
Observer Interface
1 2 3 4 5 6 7 8 9 10 11 12 package individual.cy.learn.pattern.behavioral.observer.sln2;public interface Observer { void update (String event) ; }
People Daily
1 2 3 4 5 6 7 8 9 10 11 package individual.cy.learn.pattern.behavioral.observer.sln2;public class PeopleDaily implements Observer { @Override public void update (String event) { System.out.println("Breaking news in People Daily! event = " + event); } }
New York Times
1 2 3 4 5 6 7 8 9 10 11 package individual.cy.learn.pattern.behavioral.observer.sln2;public class NewYorkTimes implements Observer { @Override public void update (String event) { System.out.println("Breaking news in New York Times! event = " + event); } }
Subject
Subject Interface
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 package individual.cy.learn.pattern.behavioral.observer.sln2;public interface Subject { void registerObserver (Observer observer) ; void unregisterObserver (Observer observer) ; void notifyObservers (String event) ; }
Feed
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 package individual.cy.learn.pattern.behavioral.observer.sln2;import java.util.ArrayList;import java.util.List;public class Feed implements Subject { private final List<Observer> observers = new ArrayList <>(); @Override public void registerObserver (Observer observer) { observers.add(observer); } @Override public void unregisterObserver (Observer observer) { observers.remove(observer); } @Override public void notifyObservers (String event) { observers.forEach(o -> o.update(event)); } }
Tester
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package individual.cy.learn.pattern.behavioral.observer.sln2;public class Tester { public static void main (String[] args) { Feed globalEvent = new Feed (); Observer newYorkTimes = new NewYorkTimes (); Observer peopleDaily = new PeopleDaily (); globalEvent.registerObserver(newYorkTimes); globalEvent.registerObserver(peopleDaily); globalEvent.notifyObservers("Violent Parade in USA" ); System.out.println("Unregister New York Times!" ); globalEvent.unregisterObserver(newYorkTimes); globalEvent.notifyObservers("Violent Parade in Canada" ); } }
1 2 3 4 Breaking news in New York Times! event = Violent Parade in USA Breaking news in People Daily! event = Violent Parade in USA Unregister New York Times! Breaking news in People Daily! event = Violent Parade in Canada
实现二
Observer
Abstract Observer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package individual.cy.learn.pattern.behavioral.observer;public abstract class AbstractObserver { protected Subject subject; public abstract void update () ; }
Binary Observer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package individual.cy.learn.pattern.behavioral.observer;public class BinaryObserver extends AbstractObserver { public BinaryObserver (Subject subject) { this .subject = subject; this .subject.attach(this ); } @Override public void update () { System.out.println("BinaryObserver.update: " + Integer.toBinaryString(subject.getState())); } }
Octal Observer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package individual.cy.learn.pattern.behavioral.observer;public class OctalObserver extends AbstractObserver { public OctalObserver (Subject subject) { this .subject = subject; this .subject.attach(this ); } @Override public void update () { System.out.println("OctalObserver.update: " + Integer.toOctalString(subject.getState())); } }
Hex Observer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package individual.cy.learn.pattern.behavioral.observer;public class HexObserver extends AbstractObserver { public HexObserver (Subject subject) { this .subject = subject; this .subject.attach(this ); } @Override public void update () { System.out.println("HexObserver.update: " + Integer.toHexString(subject.getState()).toUpperCase()); } }
Subject
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 package individual.cy.learn.pattern.behavioral.observer;import java.util.ArrayList;import java.util.List;public class Subject { private final List<AbstractObserver> observerList = new ArrayList <>(); private int state; public int getState () { return state; } public void setState (int state) { this .state = state; notifyAllObservers(); } public void attach (AbstractObserver observer) { observerList.add(observer); } public void notifyAllObservers () { observerList.forEach(AbstractObserver::update); } }
Tester
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package individual.cy.learn.pattern.behavioral.observer;public class ObserverPatternTester { public static void main (String[] args) { Subject subject = new Subject (); new HexObserver (subject); new OctalObserver (subject); new BinaryObserver (subject); System.out.println("First state change: 15" ); subject.setState(15 ); System.out.println("========================" ); System.out.println("Second state change: 10" ); subject.setState(10 ); } }
1 2 3 4 5 6 7 8 9 First state change: 15 HexObserver.update: F OctalObserver.update: 17 BinaryObserver.update: 1111 ======================== Second state change: 10 HexObserver.update: A OctalObserver.update: 12 BinaryObserver.update: 1010