聲明:文章內容根據大牛博客的內容,自己理解後,給自己做的學習筆記,文末會附上大牛博客地址鏈接。有需要溝通交流的可加我QQ羣:425120333
觀察者模式個人認爲是挺有意思的一個設計模式,居然叫做觀察者模式,那當然就有觀察者和被觀察者。這個模式比較貼近現實,
舉兩個生活中常見的例子,老師給學生上課,老師就是被觀察者,學生就是觀察者,老師在黑板上寫的每個知識點,每個學生都要去做筆記;
另一個例子就是早上訂報服務(或者訂牛奶),每一個訂購者都是觀察者,發報中心就是被觀察者,每一次發報,發報中心都要把報紙送到每個訂購者手裏。
下面用第一個例子開發:
public class OwnObserver {
public static void main(String[] args) {
Teacher teacher = new Teacher();
Student s1 = new Student("張三");
teacher.addList(s1);
Student s2 = new Student("李四");
teacher.addList(s2);
teacher.setInfo("知識點1");
System.out.println("--------------------------");
teacher.setInfo("知識點2");
}
}
class Teacher {
private String info;
List<IStudent> studentList = new ArrayList<IStudent>();
public void setInfo(String info) {
this.info = info;
System.out.println("老師在黑板上寫下了一行:" + info);
notifyAllStudent();
}
private void notifyAllStudent() {
for (IStudent student : studentList) {
student.study(this);
}
}
public void addList(IStudent student) {
studentList.add(student);
}
public void removeList(IStudent student) {
studentList.remove(student);
}
public String getInfo() {
return info;
}
}
interface IStudent {
void study(Teacher teacher);
}
class Student implements IStudent {
private String name;
public Student(String name) {
this.name = name;
}
@Override
public void study(Teacher teacher) {
System.out.println(name + "看到了老師在黑板上寫了:" + teacher.getInfo() + ",做了筆記!");
}
}
控制檯輸出:
老師在黑板上寫下了一行:知識點1
張三看到了老師在黑板上寫了:知識點1,做了筆記!
李四看到了老師在黑板上寫了:知識點1,做了筆記!
--------------------------
老師在黑板上寫下了一行:知識點2
張三看到了老師在黑板上寫了:知識點2,做了筆記!
李四看到了老師在黑板上寫了:知識點2,做了筆記!
這裏的學生可以根據需要,隨意添加刪除。這裏的觀察者模式是自己實現的,在JDK中已經有一套觀察者模式,通過繼承被觀察類和實現觀察者接口就行,
代碼更加簡單。
import java.util.Observable;
import java.util.Observer;
public class JDKObserver {
public static void main(String[] args) {
JDKTeacher teacher = new JDKTeacher();
JDKStudent s1 = new JDKStudent("張三");
teacher.addObserver(s1);
JDKStudent s2 = new JDKStudent("李四");
teacher.addObserver(s2);
teacher.setInfo("知識點1");
System.out.println("--------------------------");
teacher.setInfo("知識點2");
}
}
class JDKTeacher extends Observable {
private String info;
public void setInfo(String info) {
this.info = info;
System.out.println("老師在黑板上寫下了一行:" + info);
//這個是爲了告訴所有觀察者內容更新了,不能忘了寫
setChanged();
notifyObservers();
}
public String getInfo() {
return info;
}
}
class JDKStudent implements Observer {
private String name;
public JDKStudent(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
if (o instanceof JDKTeacher) {
JDKTeacher teacher = (JDKTeacher) o;
System.out.println(name + "看到了老師在黑板上寫了:" + teacher.getInfo() + ",做了筆記!");
}
}
}
控制檯輸出
老師在黑板上寫下了一行:知識點1
李四看到了老師在黑板上寫了:知識點1,做了筆記!
張三看到了老師在黑板上寫了:知識點1,做了筆記!
--------------------------
老師在黑板上寫下了一行:知識點2
李四看到了老師在黑板上寫了:知識點2,做了筆記!
張三看到了老師在黑板上寫了:知識點2,做了筆記!
從輸出中可以看到結果和上面的輸出結果是一模一樣的,而且代碼更加少(推薦使用這種,多線程下也不會有問題)。
通過觀察者模式可以很好的解決一對多情況下的情況,不用每次更改都要逐一通知。當然相應的缺點也很明顯就是多對一的情況不能解決
(鼠標有單擊、雙擊、移動等各種行爲,每種行爲都有相應的處理),這種情況下事件驅動模型是很好的一種解決方式。(這裏就不寫了,需要的參考下面鏈接)
參考大牛鏈接:http://www.cnblogs.com/zuoxiaolong/p/pattern7.html