1、觀察者模式:定義了對象間的一對多依賴,當一個對象改變狀态時,它的所有依賴者能自動得到通知并更新。(出版
者+訂閱者=觀察者模式)
2、java.util.observer和java.util.observable提供内置的觀察者模式支援,可以使用推和拉的方 式傳送資料,注
意:不要依賴它的通知次序。其實作步驟如下:
1>.将對象變為觀察者:
<1>.實作觀察者接口(java.util.observer)
<2>.調用addobserver()方法即将對象變為觀察者
<3>.如想退出觀察者,調用deleteobserver()即可
2>.主題發送通知:
<1>.調用setchanged()方法,标記狀态已改變
<2>.調用notifyobservers():
notifyobservers()或notifyobservers(object o)(其中o表示要傳送的資料對象)
3>.觀察者接受通知:
update(observable o,object o)
3、實作一個完整的觀察者模式示例(推模式):不使用java的内置api
1>.設計uml圖:

2>.coding
<1>.主題部分
//subject interface
public interface subject{
public void registerobserver(observer observer);
public void removeobserver(observer observer);
public void notifyobservers();
}
//mapseries:implements subject interface
import java.util.arraylist;
public class mapseries implements subject{
private arraylist<observer> observers;
private string name;
private string author;
private double price;
public mapseries(){
observers = new arraylist<observer>();
}
public void registerobserver(observer observer){
observers.add(observer);
public void removeobserver(observer observer){
int i = observers.indexof(observer);
if(i > -1){
observers.remove(i);
}
public void notifyobservers(){
for(int i = 0; i < observers.size(); i++){
observer observer = observers.get(i);
observer.update(name,author,price);
}
public void autonotify(){
notifyobservers();
public void addbook(string name, string author, double price){
this.name = name;
this.author = author;
this.price = price;
autonotify();
<2>.觀察者部分
//observer interface
public interface observer{
public void update(string name,string author,double price);
//display interface
public interface display{
public void display();
//display name and author
public class nameandauthor implements observer,display{
private subject subject;
public nameandauthor(subject subject){
this.subject = subject;
subject.registerobserver(this);
public void update(string name,string author,double price){
display();
public void display(){
system.out.println("name: " + name + "\n" + "author: " + author);
//display name and price
public class nameandprice implements observer,display{
public nameandprice(subject subject){
this.name = name;
this.price = price;
system.out.println("name: " + name + "\n" + "price: " + string.valueof(price));
//display name author price
public class nameauthorprice implements observer,display{
public nameauthorprice(subject subject){
this.author =author;
system.out.println("name: " + name + "\n"
+ "author: " + author + "\n"
+ "price: " + string.valueof(price) + "\n");
<3>.測試部分
//test this application program
public class testobserver{
public static void main(string[] args){
mapseries map = new mapseries();
nameandauthor na = new nameandauthor(map);
nameandprice np = new nameandprice(map);
nameauthorprice nap = new nameauthorprice(map);
map.addbook("head first design pattern","bufubuxing",98.00);
map.addbook("head first servlet&jsp","wenlong.meng",99.99);
map.addbook("head first ejb","dragon",87.00);
<4>.測試結果部分
4、運用java内置觀察者模式支援示例:拉模式
1、可觀察者部分
//mapseries:extend observable class
import java.util.observable;
public class mapseries extends observable{
public mapseries(){}
setchanged();
notifyobservers();//"拉"模式:背景調用notifyobservers(null)
public string getname(){
return name;
public string getauthor(){
return author;
public double getprice(){
return price;
2>.觀察者部分
import java.util.observer;
observable observable;
public nameandauthor(observable observable){
this.observable = observable;
observable.addobservser(this);
public void update(observable obs,object org){
if(obs instanceof mapseries){
mapseries map = (mapseries)obs;
this.name = map.getname();
this.author = map.getauthor();
display();
private observable observable;
public nameauthorprice(observable observable){
public void update(observable observable, object arg){
mapseries map = (mapseries)obs;
this.name = map.getname();
this.price = map.getprice();
display();
public nameandprice(observable observable){
3>.測試部分
nameauthorprice nap = new nameauthorprice(map);
map.addbook("head first design pattern","bufubuxing",98.00);
map.addbook("head first servlet&jsp","wenlong.meng",99.99);
4>.結果部分
5、運用java内置觀察者模式支援示例:推模式
arraylist al = new arraylist();
al.add(name);
al.add(author);
al.add(price);
notifyobservers(al);
//notifyobservers();//
this.author = author;
/*public string getname(){
return name;
}*/
this.observable = observable;
observable.addobserver(this);
if(org != null){
name = (string)(((arraylist)org).get(0));
author = (string)(((arraylist)org).get(1));
}
/*if(obs instanceof mapseries){
mapseries map = (mapseries)obs;
this.name = map.getname();
this.author = map.getauthor();
}*/
system.out.println("name: " + name + "\n" + "author: " + author + "\n");
observable.addobserver(this);
public void update(observable obs, object org){
if(org != null){
name = (string)(((arraylist)org).get(0));
author = (string)(((arraylist)org).get(1));
price = ((double)(((arraylist)org).get(2))).doublevalue();
display();
}
/*if(obs instanceof mapseries){
mapseries map = (mapseries)obs;
this.name = map.getname();
this.author = map.getauthor();
this.price = map.getprice();
}*/
+ "author: " + author + "\n"
+ "price: " + string.valueof(price) + "\n");
public nameandprice(observable observable){
this.observable = observable;
this.price = map.getprice();
display();
system.out.println("name: " + name + "\n" + "price: " + string.valueof(price) + "\n");
mapseries map = new mapseries();
nameandauthor na = new nameandauthor(map);
nameandprice np = new nameandprice(map);
nameauthorprice nap = new nameauthorprice(map);
map.addbook("head first design pattern","bufubuxing",98.00);
map.addbook("head first servlet&jsp","wenlong.meng",99.99);
map.addbook("head first ejb","dragon",87.00);