其他設(shè)計(jì)模式
java單例模式
java建造者模式
java策略模式
java代理模式
java觀察者模式
java適配器模式
java外觀模式
觀察者模式又叫做發(fā)布-訂閱(Publish/Subscribe)模式拂檩。
觀察者模式定義了一種一對(duì)多的依賴關(guān)系返劲,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)發(fā)生變化時(shí)尖啡,會(huì)通知所有觀察者對(duì)象含懊,使它們能夠自己更新自己。
Subject類,可翻譯成為主題或抽象通知者范抓,一般用一個(gè)抽象類或者一個(gè)接口實(shí)現(xiàn)。它把所有對(duì)觀察者對(duì)象的引用保存在一個(gè)集合里食铐,每個(gè)主題都可以有任何數(shù)量的觀察者匕垫。抽象主題提供一個(gè)接口,可以增加和刪除觀察者對(duì)象虐呻。
interface Subject {
//添加觀察者
void addObserver(Observer obj);
//移除觀察者
void deleteObserver(Observer obj);
//當(dāng)主題方法改變時(shí),這個(gè)方法被調(diào)用,通知所有的觀察者
void notifyObserver();
}
Observer類象泵,抽象觀察者,為所有的具體觀察者定義一個(gè)接口斟叼,在得到主題的通知時(shí)更新自己偶惠,這個(gè)接口叫做更新接口。抽象觀察者一般用一個(gè)抽象類或者一個(gè)接口實(shí)現(xiàn)朗涩,更新接口通常包含一個(gè)Update()方法忽孽,這個(gè)方法叫做更新方法。
interface Observer {
public void update();
}
ConcreteSubject類谢床,叫做具體主題或具體通知者兄一,將有關(guān)狀態(tài)存入具體觀察者對(duì)象,在具體主題的內(nèi)部狀態(tài)改變時(shí)萤悴,給所有登記過的觀察者發(fā)出通知瘾腰。這里舉例老師給學(xué)生布置作業(yè)。
public class TeacherSubject implements Subject {
//用來存放和記錄觀察者
private List<Observer> observers=new ArrayList<Observer>();
//記錄狀態(tài)的字符串
private String info;
@Override
public void addObserver(Observer obj) {
observers.add(obj);
}
@Override
public void deleteObserver(Observer obj) {
int i = observers.indexOf(obj);
if(i>=0){
observers.remove(obj);
}
}
@Override
public void notifyObserver() {
for (Observer observer:observers) {
observer.update();
}
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
ConcreteObserver類覆履,具體觀察者蹋盆,實(shí)現(xiàn)抽象觀察者角色所要求的更新接口费薄,以便使本身的狀態(tài)與主題狀態(tài)相協(xié)調(diào),具體觀察者角色可以保存一個(gè)指向具體主題對(duì)象的引用栖雾。
public class StudentObserver implements Observer {
//保存一個(gè)Subject的引用,以后如果可以想取消訂閱,有了這個(gè)引用會(huì)比較方便
private TeacherSubject teacher;
//學(xué)生的姓名,用來標(biāo)識(shí)不同的學(xué)生對(duì)象
private String name;
//構(gòu)造器用來注冊(cè)觀察者
public StudentObserver(String name,TeacherSubject teacher) {
this.name=name;
this.teacher = teacher;
//每新建一個(gè)學(xué)生對(duì)象,默認(rèn)添加到觀察者的行列
teacher.addObserver(this);
}
@Override
public void update() {
System.out.println(name+"得到作業(yè):"+teacher.getInfo());
}
}
測(cè)試用例
public class TestObserver {
public static void main(String []args) throws Exception {
TeacherSubject teacher=new TeacherSubject();
StudentObserver jack=new StudentObserver("jack",teacher);
StudentObserver mark=new StudentObserver("mark",teacher);
teacher.setInfo("測(cè)試題1");
teacher.notifyObserver();
teacher.setInfo("測(cè)試題2");
teacher.deleteObserver(jack);
teacher.notifyObserver();
}
}
輸出結(jié)果
jack得到作業(yè):測(cè)試題1
mark得到作業(yè):測(cè)試題1
mark得到作業(yè):測(cè)試題2
觀察者模式在android中的應(yīng)用
首先在Android中楞抡,我們往ListView添加數(shù)據(jù)后,都會(huì)調(diào)用Adapter的notifyDataChanged()方法析藕,其中使用了觀察者模式召廷。
當(dāng)ListView的數(shù)據(jù)發(fā)生變化時(shí),調(diào)用Adapter的notifyDataSetChanged函數(shù)账胧,這個(gè)函數(shù)又會(huì)調(diào)用DataSetObservable的notifyChanged函數(shù)竞慢,這個(gè)函數(shù)會(huì)調(diào)用所有觀察者(AdapterDataSetObserver)的onChanged方法,在onChanged函數(shù)中又會(huì)調(diào)用ListView重新布局的函數(shù)使得ListView刷新界面治泥。