设计模式|观察者模式

观察者模式定义了一种一对多的依赖关系, 让多个观察对像同时监听某一个对象, 这个对象在改变时会通知所有观察者。

代码 1

在这个小例子中, 由间谍 spy 扮演被观察者窃取, 当间谍发现甲国家的秘密信息后它的状态改变, 然后通知扮演观察者的乙丙国, 乙丙国在收到 spy 的信息后会做出不一样的判断。

public abstract class Country {
    protected String countryName;
    protected Spy007 spy;

    public Country(String countryName, Spy007 spy) {
        this.countryName = countryName;
        this.spy = spy;
    }

    public abstract void update();
}
public class CountryA extends Country{

    public CountryA(String countryName, Spy007 spy) {
        super(countryName, spy);
    }

    /**
     * 获取情报的方法
     */
    @Override
    public void update() {
        System.out.println(countryName+"得到情报: "+spy.getIntelligence()+" 决定与甲国开战!");
    }
}
public class CountryB extends Country{

    public CountryB(String countryName, Spy007 spy) {
        super(countryName, spy);
    }

    /**
     * 获取情报的方法
     */
    @Override
    public void update() {
        System.out.println(countryName+"得到情报: "+spy.getIntelligence()+" 决定与甲国建立关系!");
    }
}
public class Spy {
    private List<Country> countryList = new ArrayList<>();
    private String intelligence;

    /**
     * 潜入国家
     *
     * @param country
     */
    public void attach(Country country) {
        countryList.add(country);
    }

    /**
     * 离开国家, 对country不发送变更提醒
     * @param country
     */
    public void leave(Country country) {
        countryList.remove(country);
    }

    /**
     * 变更提醒
     */
    public void notifyCountry() {
        for (Country c : countryList){
            c.update();
        }
    }

    /**
     * 设置情报
     * @param intelligence
     */
    public void setIntelligence(String intelligence) {
        this.intelligence = intelligence;
    }

    /**
     * 获取情报
     * @return
     */
    public String getIntelligence() {
        return intelligence;
    }
}
public class Main {

    public static void main(String[] args) {
        Spy spy = new Spy();

        //两个国家雇佣了007, 这两个国家是观察者
        CountryA countryA = new CountryA("乙国", spy);
        CountryB countryB = new CountryB("丙国", spy);

        //间谍spy记下两个国家(记录通知对象)
        spy.attach(countryA);
        spy.attach(countryB);

        //发现情报(间谍状态改变)
        spy.setIntelligence("发现甲国研制了核武器!");

        //向两个国家汇报(通知观察者)
        spy.notifyCountry();
    }
}
//输出
乙国得到情报: 发现甲国研制了核武器! 决定与甲国开战!
丙国得到情报: 发现甲国研制了核武器! 决定与甲国建立关系!