观察者模式(Observer)

Posted fanglongxiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了观察者模式(Observer)相关的知识,希望对你有一定的参考价值。

什么是观察者模式

它定义对象间的一种一对多的依赖关系,可以在一个对象的状态/事件发生改变时,通知多个 “观察” 该对象的其他对象。

这个应该很好理解,就像订阅机制一样。当订阅的内容更新后,会推送给所有订阅者了。

注:观察者模式是一种行为模式(这类模式负责对象间的高效沟通和职责委派。)。

主要角色

抽象主题(Subject):也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。

具体主题(Concrete Subject):也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。

抽象观察者(Observer):它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。

具体观察者(Concrete Observer):实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。

注:java中已提供相关支持类,java.util.Observable 和 java.util.Observer。
Observable相关于抽象目标(Subject)的功能,Observer就是抽象观察者。查看下面的示例,再看下这两个类的源码就能很清楚。

优缺点

优点
降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
目标与观察者之间建立了一套触发机制。

缺点
当目标有很多直接或间接观察者时,通知所有观察者会花费很多时间,影响程序的效率。
如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用(目标与观察者之间的依赖关系并没有完全解除),可能导致系统崩溃。

实例demo

目标即被观察者:保存所有观察者,当变化发生后通知所有观察者。

//抽象目标类
public abstract class Subscription {
    protected List<Subscriber> subscribers = new ArrayList<Subscriber>();
    public void addSubscriber(Subscriber subscriber) {
        subscribers.add(subscriber);
    }
    
    public void deleSubscriber(Subscriber subscriber) {
        subscribers.remove(subscriber);
    }
    
    public abstract void subscriptionUpdate(String content);
}

//具体目标类
public class SubscriptionBlog extends Subscription {
    @Override
    public void subscriptionUpdate(String content) {
        for (Subscriber subscriber : subscribers) {
			subscriber.receiveNotification(content);
		}
    }
}

观察者:获得目标变化的通知,并处理。

//抽象观察者
public interface Subscriber {
    void receiveNotification(String notification);
}

//3个具体观察者
public class Subscriber1 implements Subscriber {
    @Override
    public void receiveNotification(String notification) {
        System.out.println("Subscriber1 收到通知:"+notification);
    }
}

public class Subscriber2 implements Subscriber {
    @Override
    public void receiveNotification(String notification) {
        System.out.println("Subscriber2 收到通知:"+notification);
    }
}

public class Subscriber3 implements Subscriber {
    @Override
    public void receiveNotification(String notification) {
        System.out.println("Subscriber3 收到通知:"+notification);
    }
}

客户端调用:这里目标有3次变化,每次变化观察者也是变化的,可以注意下。

public class ObserverTest {
    public static void main(String[] args) {
        Subscription subscription = new SubscriptionBlog();
        Subscriber subscriber1 = new Subscriber1();
        Subscriber subscriber2 = new Subscriber2();
        Subscriber subscriber3 = new Subscriber3();
        
        subscription.addSubscriber(subscriber1);
        subscription.addSubscriber(subscriber2);
        System.out.println("-----目标变化-----");
        subscription.subscriptionUpdate("xxx新增了一篇博客A。");
        System.out.println();
        
        subscription.addSubscriber(subscriber3);
        System.out.println("-----目标变化-----");
        subscription.subscriptionUpdate("xxx更新了一篇博客A。");
        System.out.println();
        
        subscription.deleSubscriber(subscriber2);
        System.out.println("-----目标变化-----");
        subscription.subscriptionUpdate("xxx新增了一篇博客B。");
    }
}

实例结果:

-----目标变化-----
Subscriber1 收到通知:xxx新增了一篇博客A。
Subscriber2 收到通知:xxx新增了一篇博客A。

-----目标变化-----
Subscriber1 收到通知:xxx更新了一篇博客A。
Subscriber2 收到通知:xxx更新了一篇博客A。
Subscriber3 收到通知:xxx更新了一篇博客A。

-----目标变化-----
Subscriber1 收到通知:xxx新增了一篇博客B。
Subscriber3 收到通知:xxx新增了一篇博客B。





以上是关于观察者模式(Observer)的主要内容,如果未能解决你的问题,请参考以下文章

观察者模式(Observer Pattern)

[Android&amp;Java]浅谈设计模式-代码篇:观察者模式Observer

JAVA观察者模式(observer pattern)

JDK自带的Observable和Observer实现观察者模式

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

行为类模式:观察者(Observer)