- 觀察者模式底層實現(xiàn)
- 使用java.util.Observable,java.util.Observer實現(xiàn)觀察者模式
優(yōu)點:
1:觀察者模式可以實現(xiàn)表示層和數(shù)據(jù)邏輯層的分離,定義了穩(wěn)定的消息更新傳遞機制,并抽象了更新接口,使得可以有各種各樣不同的表示層充當(dāng)具體觀察者角色。
2:觀察者模式在觀察目標(biāo)和觀察者之間建立一個抽象的耦合。觀察目標(biāo)只需要維持一個抽象觀察者的集合,無須了解其具體觀察者。由于觀察目標(biāo)和觀察者沒有緊密地耦合在一起,因此它們可以屬于不同的抽象化層次。
3:觀察者模式支持廣播通信,觀察目標(biāo)會向所有已注冊的觀察者對象發(fā)送通知,簡化了一對多系統(tǒng)設(shè)計的難度。
4:觀察者模式滿足“開閉原則”的要求,增加新的具體觀察者無須修改原有系統(tǒng)代碼,在具體觀察者與觀察目標(biāo)之間不存在關(guān)聯(lián)關(guān)系的情況下,增加新的觀察目標(biāo)也很方便。
缺點:觀察者之間有過多的細(xì)節(jié)依賴,運行效率低,程序復(fù)雜度變高。
主要用于以下情況:

image.png

image.png
觀察者模式底層實現(xiàn)
創(chuàng)建觀察者接口:
/**
* 觀察者接口
*/
public interface Observer {
void update(Subject subject);
}
創(chuàng)建主題對象:
import java.util.ArrayList;
import java.util.List;
/**
* 主題對象
*/
public class Subject {
//存放觀察者對象
protected List<Observer> list = new ArrayList<Observer>();
//新增觀察者對象
public void register(Observer observer) {
list.add(observer);
}
//刪除觀察者對象
public void remove(Observer observer) {
list.remove(observer);
}
//通知所有的觀察者更新狀態(tài)
public void notifyAllObservers() {
for (Observer observer : list) {
observer.update(this);
}
}
}
創(chuàng)建具體主題對象:
/**
* 具體主題對象
*/
public class ConcreteSubject extends Subject {
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
//主題對象值發(fā)生變化通知所有觀察者
this.notifyAllObservers();
}
}
創(chuàng)建觀察者對象:
/**
* 觀察者對象
* 頭條新聞
*/
public class ObserverHeadline implements Observer {
private String content;
@Override
public void update(Subject subject) {
content = ((ConcreteSubject) subject).getContent();
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
調(diào)用:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
/**
* 這是調(diào)用者
*/
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//創(chuàng)建一個主題對象
ConcreteSubject concreteSubject = new ConcreteSubject();
//創(chuàng)建觀察者對象,比如三個
ObserverHeadline headline1 = new ObserverHeadline();
ObserverHeadline headline2 = new ObserverHeadline();
ObserverHeadline headline3 = new ObserverHeadline();
//新增觀察者對象
concreteSubject.register(headline1);
concreteSubject.register(headline2);
concreteSubject.register(headline3);
Log.d("TAG", "------------------------------------");
//更改狀態(tài)
concreteSubject.setContent("湖人總冠軍!");
Log.d("TAG", headline1.getContent() + "");
Log.d("TAG", headline2.getContent() + "");
Log.d("TAG", headline3.getContent() + "");
Log.d("TAG", "------------------------------------");
//狀態(tài)再更改
concreteSubject.setContent("火箭總冠軍!");
Log.d("TAG", headline1.getContent() + "");
Log.d("TAG", headline2.getContent() + "");
Log.d("TAG", headline3.getContent() + "");
}
}
結(jié)果:
image.png
使用java.util.Observable,java.util.Observer實現(xiàn)觀察者模式
創(chuàng)建主題對象,并且繼承java.util.Observable:
import java.util.Observable;
/**
* 主題對象
*/
public class ConcreteSubject2 extends Observable {
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
setChanged(); //表示目標(biāo)對象已發(fā)生變化
notifyObservers(content);//通知所有觀察者
}
}
創(chuàng)建觀察者對象,并且實現(xiàn)java.util.Observer :
import java.util.*;
/**
* 觀察者對象
* 音樂新聞
*/
public class ObserverMusic implements java.util.Observer {
private String content;
@Override
public void update(Observable observable, Object o) {
content = ((ConcreteSubject2) observable).getContent();
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
調(diào)用:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
/**
* 這是調(diào)用者
*/
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ConcreteSubject2 concreteSubject2 = new ConcreteSubject2();
ObserverMusic music1 = new ObserverMusic();
ObserverMusic music2 = new ObserverMusic();
ObserverMusic music3 = new ObserverMusic();
concreteSubject2.addObserver(music1);
concreteSubject2.addObserver(music2);
concreteSubject2.addObserver(music3);
Log.d("TAG", "------------------------------------");
//更改狀態(tài)
concreteSubject2.setContent("周杰倫出新專輯了!");
Log.d("TAG", music1.getContent() + "");
Log.d("TAG", music2.getContent() + "");
Log.d("TAG", music3.getContent() + "");
Log.d("TAG", "------------------------------------");
//再更改狀態(tài)
concreteSubject2.setContent("趙雷出新專輯了!");
Log.d("TAG", music1.getContent() + "");
Log.d("TAG", music2.getContent() + "");
Log.d("TAG", music3.getContent() + "");
}
}
結(jié)果:
image.png
已完成測試!有不對的地方歡迎指出,感恩。