当前位置:   article > 正文

Java 观察者模式 详解

java 观察者模式

观察者模式是一种常见的设计模式,也称作发布-订阅模式。它主要解决了对象之间的通知依赖关系问题。在这种模式中,一个对象(称作Subject)维护着一个对象列表,这些对象(称作Observers)都需要被通知来响应某些事件。

观察者模式的好处在于它创建了松耦合的对象之间的一对多关系,使得Subject和Observers之间的耦合度降低。在Java中,通过定义接口和抽象类等方式,可以很容易实现观察者模式。

  1. 观察者模式概述

观察者模式包含两个主要角色:Subject和Observer。Subject是需要被监视的对象,Observer则是负责观察Subject的变化记录并做出相应处理的对象。

当Subject发生变化时,会通知所有的Observer,并调用其相应的回调方法(也就是Observer中定义的处理Subject变化的方法)。因此,每个Observer都需要注册到Subject中去,以便Subject在发生变化时能够通知到它们。

观察者模式总体结构如下所示:
在这里插入图片描述

其中,Subject包含一个状态(state)和一个Observer列表(observers),它有如下几个主要方法:

  • registerObserver(Observer observer):将一个Observer对象注册到Subject中。

  • removeObserver(Observer observer):将一个Observer对象从Subject中移除。

  • notifyObservers():通知所有已经注册的Observer,以便它们做出相应的处理。

Observer接口则主要定义Observer对象中需要实现的处理Subject变化的方法。在Java中,通常将Observer接口定义为如下所示:

public interface Observer {
    public void update(Object arg);
}
  • 1
  • 2
  • 3

其中,update方法用于处理Subject发生变化时的操作。

  1. Java中观察者模式的实现

在Java中,实现观察者模式有多种方式。下面介绍两种比较常见的实现方式:使用Java内置类库提供的Observer和Observable类实现和使用自定义接口实现。

2.1 使用Java内置类库提供的Observer和Observable类实现

Java内置类库提供了一个Observer接口和一个Observable类,可以方便地实现观察者模式。

Observable类实际上就是Subject,它有如下方法:

  • addObserver(Observer o):注册一个Observer对象到Observable中。

  • deleteObserver(Observer o):从Observable中删除指定的Observer对象。

  • notifyObservers():通知所有已经注册的Observer,以便它们做出相应的处理。

Observer接口同上。

下面是一个使用这种方式实现观察者模式的简单示例:

import java.util.Observable;
import java.util.Observer;

public class SimpleObservable extends Observable {
    private int data = 0;

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
        setChanged(); // 标记Subject对象的状态已发生变化
        notifyObservers(data); // 通知所有已注册的Observer对象
    }
}

public class SimpleObserver implements Observer {
    private int data;

    public void update(Observable o, Object arg) {
        if (arg instanceof Integer) {
            this.data = (Integer) arg;
            System.out.println("Data has changed to " + this.data + " in SimpleObserver.");
        }
    }
}

public class Test {
    public static void main(String[] args) {
        SimpleObservable observable = new SimpleObservable();
        SimpleObserver observer = new SimpleObserver();

        observable.addObserver(observer);
        observable.setData(1);
        observable.setData(2);
        observable.setData(3);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

这个示例中,SimpleObservable类继承了Observable,并在setData方法中使用了setChanged和notifyObservers方法,标记Subject对象的状态已发生变化并通知所有已注册的Observer对象。

SimpleObserver类实现了Observer接口,并在update方法中处理Subject发生变化时的操作。

最后,Test类将SimpleObservable和SimpleObserver组装起来,实现了一个简单的观察者模式示例。

需要注意的是,Java内置的Observable类有几个限制:

  • Observable是一个类而不是一个接口,这意味着你不能再继承其他类。

  • setChanged方法被定义为protected,因此你不能显式地调用这个方法。

  • Observer接口中只有一个update方法,而Observable没有额外的状态变量来描述它的内部状态,这使得Observer无法获得有关Observable的状态信息。

  • 如果Observable涉及到线程安全问题,你需要在使用Observable时自己处理。

2.2 使用自定义接口实现

另一种实现观察者模式的方式是使用自定义接口,这种方式比较灵活,也可以适用于一些特定场景。

下面是一个使用这种方式实现观察者模式的简单示例:

public interface Observer {
    public void update(Object obj);
}

public interface Subject {
    public void registerObserver(Observer observer);
    public void removeObserver(Observer observer);
    public void notifyObservers(Object obj);
}

public class SimpleSubject implements Subject {
    private List<Observer> observers = new ArrayList<Observer>();
    private int data = 0;

    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers(Object obj) {
        for (Observer observer : observers) {
            observer.update(obj);
        }
    }

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
        notifyObservers(data);
    }
}

public class SimpleObserver implements Observer {
    private int data;

    public void update(Object obj) {
        if (obj instanceof Integer) {
            this.data = (Integer) obj;
            System.out.println("Data has changed to " + this.data + " in SimpleObserver.");
        }
    }
}

public class Test {
    public static void main(String[] args) {
        SimpleSubject subject = new SimpleSubject();
        SimpleObserver observer = new SimpleObserver();

        subject.registerObserver(observer);
        subject.setData(1);
        subject.setData(2);
        subject.setData(3);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

这个示例中,Subject接口定义了三个方法:registerObserver、removeObserver和notifyObservers。SimpleSubject类实现了Subject接口,并在setData方法中调用了notifyObservers方法。

Observer接口定义了update方法,SimpleObserver类实现了Observer接口,并在update方法中处理Subject发生变化时的操作。

最后,Test类将SimpleSubject和SimpleObserver组装起来,实现了一个简单的观察者模式示例。

自定义接口的优点在于它的灵活性,能够适用于各种场景。另外,自己实现Observer模式通常需要写更多的代码,并且Observer对象可能需要自己维护许多状态信息。

  1. 观察者模式的优点和缺点

观察者模式具有以下优点:

  • 观察者模式将Subject和Observer之间解耦,使得它们可以独立地变化或扩展,提高了系统的灵活性和可扩展性。

  • 观察者模式建立了一种灵活的一对多关系,可以在任何时候添加或删除Observer对象,实现不同的业务需求。

  • 当Subject发生变化时,只需要通知已经注册的Observer对象,而无需通知未注册的Observer对象,从而避免了系统产生不必要的开销。

观察者模式具有以下缺点:

  • 观察者模式可能会导致系统中出现大量的细粒度对象,从而增加系统的复杂性。

  • 如果Subject和Observer之间相互依赖,会导致循环依赖问题,从而导致系统崩溃。

总之,观察者模式是一种常用的设计模式,主要解决了对象之间的通知依赖关系问题。在Java中,可以使用Java内置类库提供的Observer和Observable类或者自定义接口实现观察者模式。观察者模式具有灵活性、可扩展性和提高系统松耦合度等优点,但也会带来一些复杂性和循环依赖问题。在使用观察者模式时,需要根据具体业务场景进行权衡和选择。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/677488
推荐阅读
相关标签
  

闽ICP备14008679号