天天看點

淺談JAVA設計模式之——觀察者模式(Observer)

一、概述

定義對象間的一種一對多的依賴關系,當一個對象的狀态發生改變時,所有依賴于它的對象都得到通知并被自動更新。

二、适用性

  • 當一個抽象模型有兩個方面,其中一個方面依賴于另一方面。将這二者封裝在獨立的對象中以使它們可以各自獨立地改變和複用。
  • 當對一個對象的改變需要同時改變其它對象,而不知道具體有多少對象有待改變。
  • 當一個對象必須通知其它對象,而它又不能假定其它對象是誰。

三、參與者

  • Subject(目标) 目标知道它的觀察者。可以有任意多個觀察者觀察同一個目标。提供注冊和删除觀察者對象的接口。
  • Observer(觀察者) 為那些在目标發生改變時需獲得通知的對象定義一個更新接口。
  • ConcreteSubject(具體目标) 将有關狀态存入各ConcreteObserver對象。當它的狀态發生改變時,向它的各個觀察者發出通知。
  • ConcreteObserver(具體觀察者) 維護一個指向ConcreteSubject對象的引用。存儲有關狀态,這些狀态應與目标的狀态保持一緻。實作Observer的更新接口以使自身狀态與目标的狀态保持一緻

四、類圖

淺談JAVA設計模式之——觀察者模式(Observer)

五、示例

  • Subject
package com.lyz.design.observer;
import java.util.ArrayList;
import java.util.List;
/**
 * Subject 
 * @author binghe
 *
 */
public abstract class Citizen {
    List pols;
    String help = "normal";
    public void setHelp(String help) {
        this.help = help;
    }
    public String getHelp() {
        return this.help;
    }
    abstract void sendMessage(String help);
    public void setPolicemen() {
        this.pols = new ArrayList();
    }
    public void register(Policeman pol) {
        this.pols.add(pol);
    }
    public void unRegister(Policeman pol) {
        this.pols.remove(pol);
    }
}      
  • Observer
package com.lyz.design.observer;
/**
 * Observer 
 * @author binghe
 *
 */
public interface Policeman {
    void action(Citizen ci);
}      
  • ConcreteSubject

    HuangPuCitizen

package com.lyz.design.observer;
/**
 * ConcreteSubject 
 * @author binghe
 *
 */
public class HuangPuCitizen extends Citizen {
    public HuangPuCitizen(Policeman pol) {
        setPolicemen();
        register(pol);
    }
    public void sendMessage(String help) {
        setHelp(help);
        for(int i = 0; i < pols.size(); i++) {
            Policeman pol = pols.get(i);
            //通知警察行動
            pol.action(this);
        }
    }
}      

TianHeCitizen

package com.lyz.design.observer;
/**
 * ConcreteSubject 
 * @author binghe
 *
 */
public class TianHeCitizen extends Citizen {
    public TianHeCitizen(Policeman pol) {
        setPolicemen();
        register(pol);
    }
    public void sendMessage(String help) {
        setHelp(help);
        for (int i = 0; i < pols.size(); i++) {
            Policeman pol = pols.get(i);
            //通知警察行動
            pol.action(this);
        }
    }
}      
  • ConcreteObserver

    HuangPuPoliceman

package com.lyz.design.observer;
/**
 * ConcreteObserver 
 * @author binghe
 *
 */
public class HuangPuPoliceman implements Policeman {
    public void action(Citizen ci) {
        String help = ci.getHelp();
        if (help.equals("normal")) {
            System.out.println("一切正常, 不用出動");
        }
        if (help.equals("unnormal")) {
            System.out.println("有犯罪行為, 黃埔警察出動!");
        }
    }
}      

TianHePoliceman

package com.lyz.design.observer;
/**
 * ConcreteObserver 
 * @author binghe
 *
 */
public class TianHePoliceman implements Policeman {
    public void action(Citizen ci) {
        String help = ci.getHelp();
        if (help.equals("normal")) {
            System.out.println("一切正常, 不用出動");
        }
        if (help.equals("unnormal")) {
            System.out.println("有犯罪行為, 天河警察出動!");
        }
    }
}      
  • Test
package com.lyz.design.observer;
/**
 * Test 
 * @author binghe
 *
 */
public class Test{
    public static void main(String[] args) {
        Policeman thPol = new TianHePoliceman();
        Policeman hpPol = new HuangPuPoliceman();
        Citizen citizen = new HuangPuCitizen(hpPol);
        citizen.sendMessage("unnormal");
        citizen.sendMessage("normal");
        System.out.println("===========");
        citizen = new TianHeCitizen(thPol);
        citizen.sendMessage("normal");
        citizen.sendMessage("unnormal");
    }
}