java设计模式-观察者模式

模式定义

定义了对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。主题(Subject)是被观察的对象,而其所有依赖者(Observer)称为观察者。

设计原则

为交互对象之间的松耦合设计而努力:当两个对象之间松耦合,它们依然可以交互,但是不清楚彼此的细节。由于松耦合的两个对象之间互相依赖程度很低,因此系统具有弹性,能够应对变化。

UML类图

观察者模式实例

定义被观察者接口

/**
 * 抽象被观察者接口 * 定义了添加、删除、通知观察者方法
 */
public interface Subject {
    public void registerObserver(Observer o);

    public void removeObserver(Observer o);

    public void notifyObservers();
}

定义观察者接口

/**
 * 抽象观察者接口 * 定义了一个update()方法,
 * 当被观察者调用notifyObservers()方法时,观察者的update()方法会被回调
 */
public interface Observer {
    public void update(String message);
}

定义被观察者,实现Subject接口,对Subject接口的三个方法进行了具体实现,同时有一个List集合,用以保存注册的观察者,等需要通知观察者时,遍历该集合。

/**
 * 具体的被观察者
 */
public class ConcreteSubject implements Subject {
    private List<Observer> list;
    private String message;

    public ConcreteSubject() {
        list = new ArrayList<Observer>();
    }

    @Override
    public void registerObserver(Observer o) {
        list.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        if (!list.isEmpty())
            list.remove(o);
    }

    @Override
    public void notifyObservers() {
        for (int i = 0; i < list.size(); i++) {
            Observer observer = list.get(i);
            observer.update(message);
        }
    }

    public void send(String s) {
        this.message = s;
        System.out.println("更新消息:" + s);        //消息更新,通知所有观察者
        notifyObservers();
    }
}

定义观察者,实现Observer接口,对方法进行实现

/**
 * 具体的观察者
 */
public class ConcreteObserver implements Observer {
    private String name;
    private String message;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        this.message = message;
        read();
    }

    public void read() {
        System.out.println(name + " 收到消息:" + message);
    }
}

测试观察者模式,先创建一个被观察者对象(公司),再创建三个观察者对象(职工),公司先发布消息说今天加班,张三一听,不干了辞职,之后公司又发布消息明天放假,张三已经辞职,因此收不到消息,其他观察者(职工)可以收到消息。

/**
 * 测试观察者模式
 */
public class ObserverDemo {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();

        Observer observer1 = new ConcreteObserver("张三");
        Observer observer2 = new ConcreteObserver("李四");
        Observer observer3 = new ConcreteObserver("王五");

        subject.registerObserver(observer1);
        subject.registerObserver(observer2);
        subject.registerObserver(observer3);

        subject.send("今天加班");

        subject.removeObserver(observer1);

        subject.send("明天放假");
    }
}

运行结果

更新消息:今天加班
张三 收到消息:今天加班
李四 收到消息:今天加班
王五 收到消息:今天加班
更新消息:明天放假
李四 收到消息:明天放假
王五 收到消息:明天放假

Process finished with exit code 0

总结

  • 观察者模式是松偶合的。改变主题或观察者中的一方,另一方不会受到影响。
  • JDK中也有自带的观察者模式,但是被观察者是一个类而不是接口,限制了它的使用和复用能力。JDK内置观察者模式java.util.Observer接口, java.util.Observable类。
  • 在JavaBean和Swing中也有观察者模式的设计思想。

原文发布于微信公众号 - java工会(javagonghui)

原文发表时间:2018-04-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2202
来自专栏飞扬的花生

jsencrypt参数前端加密c#解密

      写程序时一般是通过form表单或者ajax方式将参数提交到服务器进行验证,如何防止提交的请求不被抓包后串改,虽然无法说绝对安全却给非法提交提高了难度...

3899
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

2586
来自专栏张善友的专栏

Mix 10 上的asp.net mvc 2的相关Session

Beyond File | New Company: From Cheesy Sample to Social Platform Scott Hansel...

2607
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2717
来自专栏大内老A

The .NET of Tomorrow

Ed Charbeneau(http://developer.telerik.com/featured/the-net-of-tomorrow/) Exciti...

32110
来自专栏hbbliyong

WPF Trigger for IsSelected in a DataTemplate for ListBox items

<DataTemplate DataType="{x:Type vm:HeaderSlugViewModel}"> <vw:HeaderSlug...

4064
来自专栏魂祭心

原 canvas绘制clock

4174
来自专栏闻道于事

js登录滑动验证,不滑动无法登陆

js的判断这里是根据滑块的位置进行判断,应该是用一个flag判断 <%@ page language="java" contentType="text/html...

6998
来自专栏我和未来有约会

Silverlight第三方控件专题

这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏请告知我一下。 名称 简介 截图 telerik 商 RadC...

4045

扫码关注云+社区