【设计模式轻松学】----- 观察者模式

什么是观察者模式

  观察者模式:定义对象之间的一对多依赖,当一个对象的改变状态时,它的依赖者都会收到通知并自动更新。这里就用报社、人来分析,若是有人想看报纸就能够向报社订阅,若是已经订阅的人不想看报纸能够向报社注销,而对于报社而言,它只会把报纸发给订阅的人群,这里的报社就是观察者模式中的主题(Subject),人就是观察者(Observer),观察者向主题注册本身就能够在主题改变时收到通知。java

UML图

代码实现

/**
 * 观察者模式的主题,用于注册、移除、通知观察者
 */
public interface Subject {
    /**
     * 新增观察者
     */
    void registerObserver(Observer observer);

    /**
     * 移除观察者
     */
    void removeObserver(Observer observer);

    /**
     * 通知观察者
     */
    void notifyObserver(String newspaperName);
}

/**
 * 观察者接口类
 */
public interface Observer {

    /**
     * 被通知时作的操做
     */
    void update(String newspaperName);

}

  上面时观察者模式的两个核心类,下面时具体的应用,首先是主题实现类-NewspaperOffice,observerList 保存全部的观察者,编程

import java.util.ArrayList;
import java.util.List;

public class NewspaperOffice  implements Subject{

    private List<Observer> observerList = new ArrayList<>();

    @Override
    public void registerObserver(Observer observer) {
        observerList.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observerList.remove(observer);
    }

    /**
     * 通知观察者们
     */
    @Override
    public void notifyObserver(String newspaperName) {
        observerList.forEach((b) -> b.update(newspaperName));
    }

}

  这里是具体的观察者,也就是被通知的对象数组

/**
 * 观察者A
 */
public class CustomerA implements Observer{

    private Subject subject;

    public CustomerA(Subject subject) {
        this.subject = subject;
        subject.registerObserver(this);
    }

    @Override
    public void update(String newspaperName) {
        System.out.println("CustomerA:《" + newspaperName + "》发布了");
    }

}


/**
 * 观察者B
 */
public class CustomerB implements Observer {

    private Subject subject;

    public CustomerB(Subject subject) {
        this.subject = subject;
        subject.registerObserver(this);
    }

    @Override
    public void update(String newspaperName) {
        System.out.println("CustomerB:《" + newspaperName + "》发布了");
    }

}

  测试上面写的简易观察者模式实现ide

public class ObserverTest {
    public static void main(String[] args) {
        Subject subject = new NewspaperOffice();
        new CustomerA(subject);
        // 注册观察者B
        new CustomerB(subject);
        // 通知观察者们
        subject.notifyObserver("日报A");
        System.out.println("========================================");
        subject.notifyObserver("日报B");
    }
}

  测试结果
测试

总结

  从上面的例子分析,主题和观察则都是接口,主题经过接口通知依赖它的全部观察者作某个操做(广播通讯),只要知道具体对象的列表,而不须要知道某个具体的对象,上面例子NewspaperOffice只需拥有Observer数组,至于具体的某个Observer并不关注,下降了对象之间的耦合度,这里也是设计原则"针对接口编程,不针对实现编程"的体现。this

相关文章
相关标签/搜索