文章來源:軟件祕笈--設計模式那點事兒觀察者模式(Observer Pattern),又稱爲發佈/訂閱模式。
定義:對象間的一種一對多的依賴關係,當一個對象的狀態發生改變的時候,所有依賴於他的對象都得到通知並被自動更新。
主要角色:觀察者和被觀察者。
實現:如果觀察者和被觀察者之間的的互動關係通過類的直接調用,就會增加觀察者和被觀察者之間的耦合性。在具體的實現中,我們需要面向接口編程,讓被觀察者管理觀察者對象類型的接口,然後調用接口方法更新觀察者。
類圖:
實例描述:高溫預警系統獲取溫度。如果溫度高於35度,則計算溫度所屬的預警級別發出對應的預警信息,並通知訂閱該預警信息的各個機構,如:學校,公園,個人 等。如果不高於35度的不發出預警信息。
代碼:
//被觀察者接口 package com.demo.Subject; import com.demo.Observer.IObserver; public interface ISubject { public boolean add(IObserver observer); public boolean remove(IObserver observer); public void notifyAllObserver(); public void setTemperature(float temperature); public String temperatureReport(); }
//被觀察者實現
package com.demo.Subject;
import java.util.Iterator;
import java.util.Vector;
import com.demo.Observer.IObserver;
public class Subject implements ISubject{
private float temperature;
private String waringlevel;
private Vector<IObserver> vector;
//初始化vector容器
public Subject(){
vector = new Vector<IObserver>();
}
//增加觀察者
@Override
public boolean add(IObserver observer) {
if(observer != null && !vector.contains(observer)){
return vector.add(observer);
}
return false;
}
//刪除觀察者
@Override
public boolean remove(IObserver observer) {
return vector.remove(observer);
}
//通知觀察者
@Override
public void notifyAllObserver() {
System.out.println("氣象部門發佈高溫"+this.waringlevel+"警報");
Iterator<IObserver> iterator = vector.iterator();
while(iterator.hasNext()){
(iterator.next()).update(this);
}
}
//根據溫度蛇之預警級別
@Override
public void setTemperature(float temperature) {
this.temperature = temperature;
this.invoke();
}
@Override
public String temperatureReport() {
return "溫度"+this.temperature;
}
private void invoke(){
if(this.temperature >= 35){
if(this.temperature < 37){
this.waringlevel = "黃色";
}
if(this.temperature < 40){
this.waringlevel = "橙色";
}
if(this.temperature >= 40 ){
this.waringlevel = "紅色";
}
//通知所有觀察者
this.notifyAllObserver();
}
}
}
//觀察者接口
package com.demo.Observer;
import com.demo.Subject.ISubject;
//觀察者接口響應被觀察者的變化
public interface IObserver {
public void update(ISubject subject);
}
//個人觀察者
package com.demo.Observer;
import com.demo.Subject.ISubject;
//個人觀察者
public class Person implements IObserver {
@Override
public void update(ISubject subject) {
System.out.println("個人收到高溫預警:"+subject.temperatureReport());
}
}
//公園
package com.demo.Observer;
import com.demo.Subject.ISubject;
public class Park implements IObserver{
public void update(ISubject subject) {
System.out.println("公園收到高溫預警:"+subject.temperatureReport());
}
}
//學校
package com.demo.Observer;
import com.demo.Subject.ISubject;
public class School implements IObserver{
public void update(ISubject subject) {
System.out.println("學校收到高溫預警:"+subject.temperatureReport());
}
}
//測試
package com.demo;
import java.util.Random;
import com.demo.Observer.Park;
import com.demo.Observer.Person;
import com.demo.Observer.School;
import com.demo.Subject.ISubject;
import com.demo.Subject.Subject;
public class Client {
public static void main (String [] args){
ISubject subject = new Subject();
subject.add(new Person());
subject.add(new School());
subject.add(new Park());
Random random = new Random();
for(int i = 0; i < 10; i++){
//設置隨機溫度
subject.setTemperature(random.nextInt(100));
}
}
}