设计模式之观察者模式(Observer Pattern)

模式分析:

    观察者模式又称为发布/订阅(Publish/Subscribe)模式。

   观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

UML类图:

    

接口分析:

    Observerable:被观察者接口,规定了几个方法,分别是registerObserver():表示将观察者注册到被观察者中,即“订阅”;removeObserver():表示将观察者从被观察者中移除,即“取消订阅”;notifyObservers():当被观察者状态改变的时候,这个方法被调用,通知所有已经注册的观察者。

    ConcreteObserverable:被观察者,实现了Observerable接口,对以上的三个方法进行了具体实现,同时有一个List集合,用以保存注册的观察者,等需要通知观察者时,遍历该集合即可。注意,该集合的泛型参数应该是Observer,接口类型,而不应该是具体的Observer实现类,这样做的原因是一个被观察者可能会有多个不同实现类的观察者(但都实现了Observer接口),如果限定了某一个具体的类型,那么会导致以后要加入新类型的时候而不得不修改当前类,耦合度过高,这是一个非常不好的行为。(设计原则:面向接口编程而不是面向实现编程)。

    Observer:观察者接口,规定了update()方法,当被观察者调用notifyObservers()方法时,观察者的update()方法会被回调。

    ConcreteObserver:观察者,实现了update()方法。

DEMO:

//定义被观察者
public interface Observerable {

    void registerObserver(Observer observer);

    void removeObserver(Observer observer);

    void notifyObservers();
}

//定义观察者
public interface Observer {

    public void update(int edition, float cost);
}

public class MagazineData implements Observerable {

    private List<Observer> observerList;
    private int edition;
    private float cost;

    public MagazineData(){
        observerList = new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer observer) {

        observerList.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {

        int i = observerList.indexOf(observer);
        if(i >=0){
            observerList.remove(i);
        }

    }

    @Override
    public void notifyObservers() {

        observerList.stream().forEach(item ->{
            item.update(edition, cost);
        });
    }

    public void setInfomation(int edition, float cost){

        this.edition = edition;
        this.cost = cost;

        notifyObservers();
    }
}

public class Customer implements Observer{

    private String name;
    private int edition;
    private float cost;

    public Customer(String name){
        this.name = name;
    }

    @Override
    public void update(int edition, float cost) {

        this.edition = edition;
        this.cost = cost;
        buy();
    }

    public void buy(){
        System.out.println(name+"购买了第"+edition+"期的杂志,花费了"+cost+"元。");
    }
}

public static void main(String[] args) {

        MagazineData magazineData = new MagazineData();

        Observer customerA = new Customer("A");
        Observer customerB = new Customer("B");
        Observer customerC = new Customer("C");

        magazineData.registerObserver(customerA);
        magazineData.registerObserver(customerB);
        magazineData.registerObserver(customerC);

        magazineData.setInfomation(5, 20);
}

推模型:被观察者主动向观察者推送自身的信息,可以是全部信息或者是部分信息。

拉模型:被观察者通过把自身的引用传递给观察者,需要观察者自行通过该引用来获取相关的信息。

认识Java内置的观察者模式:

  • java.util.Observerable(类)
  • java.util.Observer(接口)

使用场景:

        比如我们有两个对象,一个对象依赖于另一个对象的变化而变化,此时我们可以将这两个对象抽象出来,做成接口,利用观察者模式来进行解耦,又或者,当一个对象发生变化的时候,需要通知别的对象来做出改变,但又不知道这样的对象有多少个,此时利用观察者模式非常合适。

参考例子

猜你喜欢

转载自my.oschina.net/u/2319418/blog/1609156
今日推荐