Java中的Observer Design Pattern


今天,我将讨论称为“Observer Design Pattern”的简单且非常有用的行为设计模式。当我们希望得到有关对象状态变化的通知时,此设计模式很有用。

Observer Design Pattern 在Observer Design Pattern保持一个一对多的依赖之间的主题(可观察)及其家属(观察员以这样的方式),每当国家主题的变化,其家属得到通知。 在Observer Design Pattern是一种设计模式,在其中一个对象,叫主题,保持其家属,被称为列表的观察员,并通知他们自动的任何状态变化,通常是通过调用他们的方法之一。 当我们希望在对象状态发生变化时收到通知时,将使用“Observer Design Pattern”。 Observer Design Pattern是二十三个众所周知的“四人一组”设计模式之一,该模式定义了一对多的依赖对象,因此,当一个对象更改状态时,其所有依赖项都将得到通知并自动更新。 在观察者设计模式主要是用来实现分布式事件处理,在“事件驱动”系统。 在这样的系统中,主题通常被称为“事件源”,而观察者被称为“事件源”。 大多数现代语言都有内置的“事件”构造,可实现观察者模式组件。 Java还提供了Observer和Observable来支持用于实现观察者模式的内置事件构造。这些从Java 1开始可用。 但是,在Java 9这些被宣布弃用/过时的,因为事件模型的支持Observer,并Observable是非常有限的,通知被传递的顺序Observable是不确定的,并且状态变化不是一个换一个对应于通知。对于更丰富的事件模型,请考虑使用该java.beans程序包。为了在线程之间进行可靠且有序的消息传递,请考虑使用java.util.concurrent程序包中的并发数据结构之一。有关反应式流样式的编程,请参阅FlowAPI。(有关更多信息,请参见Deprecate Observer和Observable)。
观察者设计模式

observerdesignpattern.png

现在是一个示例,以了解Observer Design Pattern的实现。

假设有一些公众人物,例如政客或名人,有一些追随者。每当这些公众人物发表任何推文时,已注册的关注者都会收到有关此事的通知。

使用Observer Design Pattern的推特通知示例 首先,我们将定义Subject接口:

package org.trishinfotect.observer;
public interface Subject {
    public void addSubscriber(Observer observer);
    public void removeSubscriber(Observer observer);
    public void notifySubscribers(String tweet);
}

然后我们将创建Observer接口:

package org.trishinfotect.observer;
public interface Observer {
    public void notification(String handle, String tweet);
}

然后,我们将创建名为PublicFigure的具体主题类:

package org.trishinfotect.observer;
import java.util.ArrayList;
import java.util.List;
public class PublicFigure implements Subject {
    protected List<Observer> observers = new ArrayList<Observer>();
    protected String name;
    protected String handle;
    public PublicFigure(String name, String handle) {
        super();
        this.name = name;
        this.handle = "#" + handle;
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public String getHandle() {
        return handle;
    }
    public void tweet(String tweet) {
        System.out.printf("\nName: %s, Tweet: %s\n", name, tweet);
        notifySubscribers(tweet);
    }

    @Override
    public synchronized void addSubscriber(Observer observer) {
        observers.add(observer);
    }
    @Override
    public synchronized void removeSubscriber(Observer observer) {
        observers.remove(observer);
    }
    @Override
    public void notifySubscribers(String tweet) {
        observers.forEach(observer -> observer.notification(handle, tweet));
    }

}

请注意,我们有用于添加和删除关注者的API 。我们也有用于通知关注者的API 。而且我们还有API可以鸣叫。推特API确实会通知其注册的关注者。在通知关注者的同时,主题还提供有关所做更改的信息。在我们的示例中,其推文发生了变化。因此,它位于通知的参数中。因此,简而言之,主题还应该将更改的上下文提供给其关注者以进行通知。没有它,观察者模式将不会非常有效。每个主题都维护其关注者列表。

现在,我们将定义Follower类:

package org.trishinfotect.observer;
public class Follower implements Observer {
    protected String name;
    public Follower(String name) {
        super();
        this.name = name;
    }
    @Override
    public void notification(String handle, String tweet) {
        System.out.printf("'%s' received notification from Handle: '%s', Tweet: '%s'\n", name, handle, tweet);
    }
}

现在,是时候编写一个Main程序来执行和测试输出了:

package org.trishinfotect.observer;
public class Main {
    public static void main(String args[]) {
        PublicFigure bobama = new PublicFigure("Barack Obama", "bobama");
        PublicFigure nmodi = new PublicFigure("Narendra Modi", "nmodi");
        Follower ajay = new Follower("Ajay");
        Follower vijay = new Follower("Vijay");
        Follower racheal = new Follower("Racheal");
        Follower micheal = new Follower("Micheal");
        Follower kim = new Follower("Kim");
     bobama.addSubscriber(ajay);
        bobama.addSubscriber(vijay);
        bobama.addSubscriber(racheal);
        bobama.addSubscriber(micheal);
        bobama.addSubscriber(kim);
        nmodi.addSubscriber(ajay);
        nmodi.addSubscriber(vijay);
        nmodi.addSubscriber(racheal);
        nmodi.addSubscriber(micheal);
        nmodi.addSubscriber(kim);
        bobama.tweet("Hello Friends!");
        nmodi.tweet("Vande Matram!");
        bobama.removeSubscriber(racheal);
        bobama.tweet("Stay Home! Stay Safe!");
    }
}

这是输出:

Name: Barack Obama, Tweet: Hello Friends!
'Ajay' received notification from Handle: '#bobama', Tweet: 'Hello Friends!'
'Vijay' received notification from Handle: '#bobama', Tweet: 'Hello Friends!'
'Racheal' received notification from Handle: '#bobama', Tweet: 'Hello Friends!'
5
'Micheal' received notification from Handle: '#bobama', Tweet: 'Hello Friends!'
6
'Kim' received notification from Handle: '#bobama', Tweet: 'Hello Friends!'
Name: Narendra Modi, Tweet: Vande Matram!
'Ajay' received notification from Handle: '#nmodi', Tweet: 'Vande Matram!'
'Vijay' received notification from Handle: '#nmodi', Tweet: 'Vande Matram!'
'Racheal' received notification from Handle: '#nmodi', Tweet: 'Vande Matram!'
'Micheal' received notification from Handle: '#nmodi', Tweet: 'Vande Matram!'
'Kim' received notification from Handle: '#nmodi', Tweet: 'Vande Matram!'

Name: Barack Obama, Tweet: Stay Home! Stay Safe!
'Ajay' received notification from Handle: '#bobama', Tweet: 'Stay Home! Stay Safe!'
'Vijay' received notification from Handle: '#bobama', Tweet: 'Stay Home! Stay Safe!'
'Micheal' received notification from Handle: '#bobama', Tweet: 'Stay Home! Stay Safe!'
'Kim' received notification from Handle: '#bobama', Tweet: 'Stay Home! Stay Safe!'

请注意,当我从(Barak Obama)的关注者列表中取消注册“ Racheal”时,她停止接收通知。

请不要以为这是高音扬声器的工作方式:)

这是一个非常小的示例,用于演示观察者设计模式的结构,代码和功能。

高音扬声器拥有一个实际的生产系统,该系统能够为每个用户维护数百万个关注者。因此,这不适合这种同步通知方法。要使高音扬声器正常工作还涉及许多其他组件。

就这样!我希望我们对Observer Design Pattern的实现有所了解。


原文链接:http://codingdict.com