Mike Liu c5a4068e84
docs: Translation for zh (#1805)
* add state and callback pattern

* add command and template-method pattern

* add iterator pattern

* add bridege and DI pattern

* fix issue #1600

* add converter,proxy,visitor pattern

* add caching,composite,delegation,dirty-flag,interpreter patterns

* add dao and producer-consumer

* add dto and provate class data pattern

* fix #1646 png path problems

* fix #1646 composite png path case problem

* add abstract document pattern and version-number pattern

* add ambassador pattern

* add acyclic-visitor and api-gateway pattern

* add abstract-factory pattern

* add active-object pattern

* add aggregator-microservices and arrange-act-assert pattern

* update async-method-invocation pattern

* add balking and business-delegate pattern

* add bytecode and circuit-break pattern

* update arrange/act/assert pattern problems

* add csch pattern

* add language code, correct pic path

* #1805 update permalink

Co-authored-by: Subhrodip Mohanta <subhrodipmohanta@gmail.com>
Co-authored-by: Mike <admin@xiaod.info>
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
2021-08-01 20:25:54 +05:30
..
2021-08-01 20:25:54 +05:30

layout, title, folder, permalink, categories, language, tags
layout title folder permalink categories language tags
pattern Observer observer /patterns/observer/ Behavioral zh
Gang Of Four
Reactive

Also known as

又被称为

家属,发布订阅模式

目的

定义一种一对多的对象依赖关系这样当一个对象改变状态时,所有依赖它的对象都将自动通知或更新。

解释

真实世界例子

在遥远的土地上生活着霍比特人和兽人的种族。他们都是户外生活的人所以他们密切关注天气的变化。可以说他们不断地关注着天气。

通俗的说

注册成为一个观察者以接收对象状态的改变。

维基百科说

观察者模式是这样的一种软件设计模式:它有一个被称为主题的对象,维护着一个所有依赖于它的依赖者清单,也就是观察者清单,当主题的状态发生改变时,主题通常会调用观察者的方法来自动通知观察者们。

编程示例

让我们先来介绍天气观察者的接口以及我们的种族,兽人和霍比特人。

public interface WeatherObserver {

  void update(WeatherType currentWeather);
}

@Slf4j
public class Orcs implements WeatherObserver {

  @Override
  public void update(WeatherType currentWeather) {
    LOGGER.info("The orcs are facing " + currentWeather.getDescription() + " weather now");
  }
}

@Slf4j
public class Hobbits implements WeatherObserver {

  @Override
  public void update(WeatherType currentWeather) {
    switch (currentWeather) {
      LOGGER.info("The hobbits are facing " + currentWeather.getDescription() + " weather now");
  }
}

然后这里是不断变化的天气。

@Slf4j
public class Weather {

  private WeatherType currentWeather;
  private final List<WeatherObserver> observers;

  public Weather() {
    observers = new ArrayList<>();
    currentWeather = WeatherType.SUNNY;
  }

  public void addObserver(WeatherObserver obs) {
    observers.add(obs);
  }

  public void removeObserver(WeatherObserver obs) {
    observers.remove(obs);
  }

  /**
   * Makes time pass for weather.
   */
  public void timePasses() {
    var enumValues = WeatherType.values();
    currentWeather = enumValues[(currentWeather.ordinal() + 1) % enumValues.length];
    LOGGER.info("The weather changed to {}.", currentWeather);
    notifyObservers();
  }

  private void notifyObservers() {
    for (var obs : observers) {
      obs.update(currentWeather);
    }
  }
}

这是完整的示例。

    var weather = new Weather();
    weather.addObserver(new Orcs());
    weather.addObserver(new Hobbits());

    weather.timePasses();
    // The weather changed to rainy.
    // The orcs are facing rainy weather now
    // The hobbits are facing rainy weather now
    weather.timePasses();
    // The weather changed to windy.
    // The orcs are facing windy weather now
    // The hobbits are facing windy weather now
    weather.timePasses();
    // The weather changed to cold.
    // The orcs are facing cold weather now
    // The hobbits are facing cold weather now
    weather.timePasses();
    // The weather changed to sunny.
    // The orcs are facing sunny weather now
    // The hobbits are facing sunny weather now

Class diagram

alt text

应用

在下面任何一种情况下都可以使用观察者模式

  • 当抽象具有两个方面时,一个方面依赖于另一个方面。将这些方面封装在单独的对象中,可以使你分别进行更改和重用
  • 当一个对象的改变的同时需要改变其他对象,同时你又不知道有多少对象需要改变时
  • 当一个对象可以通知其他对象而无需假设这些对象是谁时。换句话说,你不想让这些对象紧耦合。

典型用例

  • 一个对象的改变导致其他对象的改变

Java中的例子

鸣谢