標籤:java設計模式 觀察者模式 松耦合 設計模式 觀察者
今天學習了一下觀察者模式,做一下總結。
什麼是觀察者模式?
觀察者模式:定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都將得到通知並被自動更新。
觀察者模式也叫“依賴”或者“發布——訂閱”模式。舉一些例子來說明什麼是觀察者模式。
比如訂閱者與報刊之間就屬於目標(subject)與觀察者(observer)關係。每一個訂閱者相當於一個觀察者,而這些觀察者是依賴於出版社的,當出版社的狀態發生改變時即就是有新的期刊時,所有依賴於它的訂閱者將得到通知,並會收到最新的報刊。
再比如我們程式中例子,資料與介面之間的關係。一個表格對象和一個柱狀圖對象可以使用不同的表現形式描述同一一個應用的資料對象的資訊。當資料對象的資訊改變時,這些介面裡的資料也將會得到改變。而表格對象與柱狀圖對象是沒有依賴關係的。
觀察者模式的參與者:
- Subject(目標)
目標知道它的觀察者,但是不知道具體是誰。可以有任意多個觀察者觀察同一個目標。
提供註冊和刪除觀察對象的介面
- Observer(觀察者)
為那些在目標發生改變時需要獲得通知的對象定義一個更新介面。
- ConcreteSubject(具體目標)
將有關狀態存入各ConcretSubject對象
當它的狀態發生改變時,向他的各個觀察者發出通知。
- ConcreteObserver(具體觀察者)
維護一個指向ConcreteSubjec對象的引用。
儲存有關狀態,將這些狀態與目標的狀態保持一致
實現Observer的更新介面以使自身狀態與目標的狀態保持一致。
為什麼要使用觀察者模式?
將一個系統分割成一些列相互協作的類時有一個副作用:需要維護相關對象間的一致性。而這個時候,維護他們之間的一致性是非常不容易的,因為他們之間緊密耦合,相互依賴,這樣重用性降低。而觀察者模式是松耦合的,因此重用性會得到提高。
什麼時候使用觀察者模式?
- 當一個物件模型有兩個方面,其中一個方面依賴於另一個方面。將這二者封裝在獨立的對象中以使他們可以各自獨立的改變和複用。
- 當對一個對象的改變需要同時改變其他對象,而不知道具體有多少對象有待改變。
- 當一個對象必須通知其他對象,而他又不能假定其他對象是誰。也就是說,我們不希望這些對象是緊密耦合。
如何使用觀察者模式?
下面通過一個樣本來說明。
/* * 出版社的抽象介面 */public interface Subject { //移除觀察者 public void removeObserver(Observer o); //添加觀察者 public void addObserver(Observer o); //通知觀察者 public void notifyObservers();}/* * 具體的目標對象 這裡假定為“讀者出版社” */public class ConcreteSubject implements Subject{private ArrayList<Observer> observers;private String book;public ConcreteSubject() {observers = new ArrayList<Observer>();}@Overridepublic void removeObserver(Observer o) {int i= observers.indexOf(o);if(i>=0) {observers.remove(i);}}@Overridepublic void addObserver(Observer o) {observers.add(o);}@Overridepublic void notifyObservers() {for(int i=0;i<observers.size();i++) {observers.get(i).update(book);}}//設定狀態資訊的改變方法 當有新書時 可通過此方法進行添加public void setState(String book) {this.book = book;}//通過此方法 訂閱者(observer)可以主動得到目標(subject)中的書public String getState() {return book;}}/* * 觀察者的抽象介面,擁有一個update()方法 當目標(subject)狀態改變時 調用此方法 */public interface Observer {public void update(String book);}/* * 訂閱者共有的介面 張三和李四訂閱者都必須實現這個介面 因為他們有共同的方法display */public interface DisplayElement {public void display();}/* * 訂閱者 李四 */public class Observer1 implements Observer,DisplayElement{private Subject subject;private String book;public Observer1(Subject subject) {this.subject = subject;subject.addObserver(this);}@Overridepublic void update(String book) {this.book = book;display();}@Overridepublic void display() {System.out.println("Observer1 收到了一本新書:"+book);}}/* * 訂閱者 張三 */public class Observer2 implements Observer,DisplayElement{private String book;private Subject subject;public Observer2(Subject subject) {this.subject = subject;subject.addObserver(this);}@Overridepublic void update(String book) {this.book = book;display();}@Overridepublic void display() {System.out.println("observer2 收到了一本新書:"+book);}}public class ObserverTest {public static void main(String[] args) {ConcreteSubject subject = new ConcreteSubject();Observer1 zhangsan = new Observer1(subject);Observer2 lisi = new Observer2(subject);subject.setState("讀者第一刊");subject.notifyObservers();}}
Java 設計模式之觀察者模式