likes
comments
collection
share

java-观察者模式

作者站长头像
站长
· 阅读数 74

java-观察者模式

  • 观察者模式介绍
  • 观察者模式UML
  • 观察者模式的设计原则
  • 观察者模式-java内置实现
  • 观察者模式-google实现
  • 观察则模式-手写demo
  • 观察者模式使用场景

观察者模式介绍

观察者模式是一种常用的设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生改变时,所有依赖于它的观察者对象都会得到通知并且自动更新。(观察者模式又叫做发布订阅模式)

观察者模式的核心思想是解耦,它将观察者和主题解耦,让它们之间的依赖变得松散。在观察者模式中,主题只知道观察者的存在,并不知道观察者的具体实现。当主题状态发生改变时,它只需要通知观察者即可,而不需要关心观察者的具体实现。


观察者模式UML

观察者模式的UML图如下所示:

java-观察者模式


观察者模式的设计原则

观察者模式满足的设计原则包括:开闭原则、单一职责原则、依赖倒置原则。其中,开闭原则指的是观察者模式允许增加观察者类而无需修改主题类代码,从而符合开闭原则;单一职责原则指的是主题类只负责管理观察者,不涉及具体业务逻辑,符合单一职责原则;依赖倒置原则指的是主题类和观察者类都依赖于抽象,符合依赖倒置原则。


观察者模式-java内置实现

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

public class ObserverPatternDemo {
    public static void main(String[] args){
        Subject subject = new Subject();
        new BinaryObserver(subject);
        new OctalObserver(subject);
        new HexaObserver(subject);

        System.out.println("First state change: 15");
        subject.setState(15);
        System.out.println("Second state change: 10");
        subject.setState(10);
    }
}

class Subject extends Observable {
    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        setChanged();
        notifyObservers();
    }
}

class BinaryObserver implements Observer {
    public BinaryObserver(Subject subject) {
        subject.addObserver(this);
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("Binary String: " + Integer.toBinaryString(((Subject) o).getState()));
    }
}

class OctalObserver implements Observer {
    public OctalObserver(Subject subject) {
        subject.addObserver(this);
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("Octal String: " + Integer.toOctalString(((Subject) o).getState()));
    }
}

class HexaObserver implements Observer {
    public HexaObserver(Subject subject) {
        subject.addObserver(this);
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("Hex String: " + Integer.toHexString(((Subject) o).getState()).toUpperCase());
    }
}

以上代码演示了如何在Java使用内置的观察者模式。在这个例子中,我们创建了一个Subject类,它继承了Java内置的Observable类,并且在Subject类中定义了一个状态state。当Subject类的状态发生改变时,会调用setChanged()方法和notifyObservers()方法来通知观察者。BinaryObserver、OctalObserver和HexaObserver是观察者类,它们在构造函数中注册到Subject类中。当Subject类的状态发生改变时,它们会接收到通知并且自动更新。


观察者模式-Google Guava实现

观察者模式-google实现

Google Guava库提供了观察者模式的实现,我们可以使用它来简化观察者模式的使用。

观察者模式在Google Guava库中被称为事件总线(EventBus),它提供了一个事件总线(EventBus)类,我们可以使用它来实现观察者模式。

下面是一个使用Google Guava库实现观察者模式的例子:

首先,我们需要引入Google Guava库的依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.2-jre</version>
</dependency>

然后,我们需要定义一个事件类(即主题类):

public class OrderEvent {
    private String orderId;

    public OrderEvent(String orderId) {
        this.orderId = orderId;
    }

    public String getOrderId() {
        return orderId;
    }
}

接着,我们需要定义一个观察者类:

public class OrderObserver {
    @Subscribe
    public void handleOrderEvent(OrderEvent event) {
        System.out.println("Received order event, order id: " + event.getOrderId());
    }
}

在这个观察者类中,我们使用了@Subscribe注解来标记handleOrderEvent()方法,表示这个方法是用来处理事件的。

最后,我们需要在我们的应用程序中创建一个事件总线(EventBus)对象,并且将观察者注册到事件总线上:

public class App {
    public static void main(String[] args) {
        EventBus eventBus = new EventBus();
        OrderObserver orderObserver = new OrderObserver();
        eventBus.register(orderObserver);
        eventBus.post(new OrderEvent("1234567890"));
    }
}

在这个应用程序中,我们创建了一个事件总线(EventBus)对象,并且将观察者注册到事件总线上。然后,我们使用eventBus.post()方法来发布事件,这样就会触发观察者的处理方法。

需要注意的是,我们还需要在观察者类中定义一个无参构造函数,否则Google Guava库无法正确地实例化观察者对象。

总的来说,使用Google Guava库可以让我们更加方便地实现观察者模式,从而帮助我们简化代码,并且提高开发效率。


观察者模式-手写demo

代码实现

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

interface Observer {
    void update(int state);
}

class Subject {
    private int state;
    private List<Observer> observers = new ArrayList<>();

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        notifyAllObservers();
    }

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

    public void notifyAllObservers() {
        for (Observer observer : observers) {
            observer.update(state);
        }
    }
}

class BinaryObserver implements Observer {
    public BinaryObserver(Subject subject) {
        subject.attach(this);
    }

    @Override
    public void update(int state) {
        System.out.println("Binary String: " + Integer.toBinaryString(state));
    }
}

class OctalObserver implements Observer {
    public OctalObserver(Subject subject) {
        subject.attach(this);
    }

    @Override
    public void update(int state) {
        System.out.println("Octal String: " + Integer.toOctalString(state));
    }
}

class HexaObserver implements Observer {
    public HexaObserver(Subject subject) {
        subject.attach(this);
    }

    @Override
    public void update(int state) {
        System.out.println("Hex String: " + Integer.toHexString(state).toUpperCase());
    }
}

public class ObserverPatternDemo {
    public static void main(String[] args) {
        Subject subject = new Subject();
        new BinaryObserver(subject);
        new OctalObserver(subject);
        new HexaObserver(subject);

        System.out.println("First state change: 15");
        subject.setState(15);
        System.out.println("Second state change: 10");
        subject.setState(10);
    }
}

手写demo说明

手写demo实现了一个观察者模式的例子,其中包括了Subject主题类和Observer观察者接口,以及BinaryObserver、OctalObserver和HexaObserver三个观察者类。当Subject类的状态发生改变时,会调用notifyAllObservers()方法来通知观察者,而观察者类则会接收到通知并且自动更新。


观察者模式使用场景

观察者模式的使用场景包括:

  • 当一个对象的改变需要同时改变其他对象时
  • 当一个对象的改变需要通知其他对象时
  • 当一个对象的改变需要通知一组对象时

比如,当我们需要在一个系统中实现事件处理机制时,就可以使用观察者模式。在这个系统中,事件源是主题,它负责产生事件并且通知所有的观察者;观察者则负责接收事件并且进行处理。

另外,观察者模式还常用于GUI开发、消息系统等领域中。

总结

观察者模式是一种常用的设计模式,它允许多个观察者对象同时监听某一个主题对象,并且当主题对象状态发生改变时,所有依赖于它的观察者对象都会得到通知并且自动更新。在Java中,观察者模式已经被内置实现,可以很方便地使用。同时,我们也可以手写实现观察者模式,以便更好地理解其原理和应用。观察者模式的使用场景包括:当一个对象的改变需要同时改变其他对象时、当一个对象的改变需要通知其他对象时、当一个对象的改变需要通知一组对象时。

转载自:https://juejin.cn/post/7243715171947610167
评论
请登录