觀察者模式---先看再買,絕不後悔

        聲明:文章內容根據大牛博客的內容,自己理解後,給自己做的學習筆記,文末會附上大牛博客地址鏈接。有需要溝通交流的可加我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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章