`
youyu4
  • 浏览: 425243 次
社区版块
存档分类
最新评论

Java设计模式十:观察者模式(Observer)

 
阅读更多

观察者模式定义了对象间的一种一对多依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
它将观察者和被观察者的对象分离开。提高了应用程序的可维护性和重用性。
实现观察者模式有很多形式,一种是“注册---通知---撤销注册”的形式。
观察者Observer:所有潜在的观察者必须实现观察者接口,这个接口只有update方法,当主题改变时,它被调用。
具体观察者ConcreteObserver: 具体观察者可以是任何实现了Observer接口的类。观察者必须注册具体主题,一边接收更新。
可观察者Subject: 主题接口,即可观察者Observable,对象使用此接口注册为观察者,或者把自己从观察者中删除,每个主题可以有多个观察者。
具体可观察者ConcreteSubject: 一个具体主题实现了主题接口,除了注册和撤销之外,具体主题还实现了notifyObservers()方法,这个方法用来在主题状态改变时更新所有观察者。具体主题也可能有设置和获取状态的方法。

类图:


 

//实例:
public interface Observer
{
    public void update(float temprature);
}

public class ConcreteObserver implements Observer
{
    private float temperature;
    private final Subject subject;

    public ConcreteObserver(final Subject subject)
    {
        this.subject = subject;
        this.subject.registerObserver(this);
    }

    public float getTemperature()
    {
        return temperature;
    }

    public void setTemperature(final float temperature)
    {
        this.temperature = temperature;
    }

    @Override
    public void update(final float temperature)
    {
        this.temperature = temperature;
    }
}

public interface Subject
{
    public void registerObserver(Observer o);

    public void removeObserver(Observer o);

    public void notifyObservers();

}

public class ConcreteSubject implements Subject
{
    private final List<Observer> observers;
    private float temperature;

    public float getTemperature()
    {
        return temperature;
    }

    private void temperatureChanged()
    {
        this.notifyObservers();
    }

    public void setTemperature(final float temperature)
    {
        this.temperature = temperature;
        this.temperatureChanged();
    }

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

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

    @Override
    public void removeObserver(final Observer o)
    {
        if (observers.indexOf(o) >= 0)
        {
            observers.remove(o);
        }
    }

    @Override
    public void notifyObservers()
    {
        for (final Observer o : observers)
        {
            o.update(temperature);
        }
    }
}

public class Client
{
    public static void main(final String[] args)
    {
        final ConcreteSubject sb = new ConcreteSubject();
        sb.setTemperature((float) 20.00);

        final Observer o = new ConcreteObserver(sb);
        sb.setTemperature((float) 21.00);

    }
}

 

 

观察者模式的应用场景:

1、 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。

2、 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。

观察者模式的优点:

1、 SubjectObserver之间是松偶合的,分别可以各自独立改变。

2、 Subject在发送广播通知的时候,无须指定具体的ObserverObserver可以自己决定是否要订阅Subject的通知。

3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。

观察者模式的缺陷:

1、 松偶合导致代码关系不明显,有时可能难以理解。(废话)

2、 如果一个Subject被大量Observer订阅的话,在广播通知的时候可能会有效率问题。(毕竟只是简单的遍历)

 

 

 

 

JavaJava内置的观察者模式

 

如何实现简单的观察者模式

接下来我们实现壹個简单的被观察者类 ExampleObservable ,代码如下:

1
2
3
4
5
6
7
8
9
10
11
import java.util.Observable;
 
public class ExampleObservable extends Observable {
    int data = 0;
     
    public void setData(int data){
        this.data = data;
        this.setChanged();//标记此 Observable对象为已改变的对象
                this.notifyObservers();//通知所有的观察者
    }
}

再实现壹個观察者类 ExampleObserver,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
import java.util.Observable;
import java.util.Observer;
 
public class ExampleObserver implements Observer {
        //有被观察者发生变化,自动调用对应观察者的update方法
        @Override
    public void update(Observable object, Object argument) {
                //通过强制类型转换获取被观察者对象
                ExampleObservable example = (ExampleObservable)object;
        System.out.println("example.data changed, the new value of data is " + example.data);
    }
}
我们再写壹個简单的测试类来测试下它是否运行正确,代码如下:
1
2
3
4
5
6
7
8
9
10
public class Main {
 
    public static void main(String[] args) {
        ExampleObservable example = new ExampleObservable();
        example.addObserver(new ExampleObserver());//给example这个被观察者添加观察者,允许添加多個观察者
        example.setData(2);
        example.setData(-5);
        example.setData(9999);
    }
}

运行之后在控制台输出如下结果:

1
2
3
example.data changed, the new value of data is 2
example.data changed, the new value of data is -5
example.data changed, the new value of data is 9999

通过输出结果我们可以了解到,当 ExampleObservable 类的实例 example 的成员变量 data 的值发生改变时,ExampleObserver 对象都能够监测到,然后调用 update() 方法打印壹句话到控制台,说明以上的结果是符合我们预期的。

既是观察者又是被观察者

对于壹個类而言,可以既是观察者又是被观察者,只要既继承 Observable 类,又实现 Observer 接口就可以了。接下来给出壹個类似的例子。例子中 ObserverA 和 ObserverB 既是观察者又是被观察者,它们互相监听着对方的改变。

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
//ObserverA.java
import java.util.Observable;
import java.util.Observer;
 
public class ObserverA extends Observable implements Observer {
 
    @Override
    public void update(Observable object, Object arg) {
        ObserverB observerB = (ObserverB)object;
        System.out.println("observerB changed, the new value of observerB.data is " + observerB.data);
        this.setChanged();
        this.notifyObservers();
    }
}
 
//ObserverB.java
import java.util.Observable;
import java.util.Observer;
 
public class ObserverB extends Observable implements Observer {
 
    int data = 0;
    @Override
    public void update(Observable object, Object arg) {
        System.out.println("ObserverB found that ObserverA changed...");
    }
     
    public void setData(int data){
        this.data = data;
        this.setChanged();
        this.notifyObservers();
    }
}
 
//Main.java
import net.oschina.bairrfhoinn.multiply.ObserverA;
import net.oschina.bairrfhoinn.multiply.ObserverB;
 
public class Main {
 
    public static void main(String[] args) {
        ObserverA a = new ObserverA();
        ObserverB b = new ObserverB();
         
        a.addObserver(b);
        b.addObserver(a);
         
        b.setData(2);
    }
}
运行之后的结果为:
1
2
observerB changed, the new value of observerB.data is 2
ObserverB found that ObserverA changed...

之所以会出现上述运行结果,最初 ObserverA 和 ObserverB 相互之间作为观察者与被观察者,但是 ObserverB 的实例 b 先调用的 setData() 方法,然后 ObserverA 的实例 a 观察到了这個变化,于是调用了本类的 update 方法打印出了第壹行,紧接着 ObserverA 的 update() 方法在方法体中声明了自己发生了变化,于是 ObserverB 观察了这個情况,也调用了自身的 update() 方法并打印了第二句话。

 

 

 

 

  • 大小: 13.2 KB
分享到:
评论

相关推荐

    Java 设计模式-观察者模式(Observer)

    结合微信公众号讲解观察者模式,生动形象,关键是上手快啊

    详解Observer Pattern(观察者模式)在Java中的使用原理

    我们说学习Java应该从Swing开始,那么学习Swing最重要的思想就是对于观察者模式的理解(Observer Pattern)。因为,该设计模式在Java Swing框架中贯穿了始终。对于C#的委托、代理概念所使用的Callback(回调模式--...

    Java设计模式 设计模式介绍

    1、爪哇语言结构性模式之变压器模式介绍 2、爪哇语言抽象工厂创立性模式介绍 3、工厂方法创立性模式介绍 4、单态创立性模式介绍 5、单态创立性模式介绍 6、观察者模式介绍7、责任链模式 8、设计模式之Observer 9、...

    设计模式 观察者 发布/订阅 Observer

    Observer (观察者模式) 又叫做发布/订阅(Publish/Subscribe)模式。 当一个对象的改变同时会影响其他对象的行为的时候,可以使用此设计模式。 l 主题对象 :一个需要被关注的主题对象,这个主题对象改变会影响...

    Java 观察者模式的浅析

    Java 观察者模式的浅析 简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象。这样一个主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象,使这些观察者...

    Java内置观察者模式

    观察者模式:对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化,这个例子是java内置观察者模式

    JAVA设计模式之行为模式

    这是JAVA设计模式中属于行为模式的部分,包括Template(模板模式)、Chain of Responsibility(责任链模式)、Memento(纪念品模式)、Mediator(中介模式)、Strategy(策略模式)、State 、Observer(观察者模式)、Visitor...

    java观察者模式介绍

    Observer模式定义对象间的一对多的依赖关系,当一个对象(被观察者)的状态发生改变...从名字上可以清楚的看出两者在Observer 设计模式中分别扮演的角色:Observer是观察者角色,Observable是被观察目标(subject)角色。

    [Java设计模式(第2版)(Design.Patterns.in.Java).John.Metsker

    第9章 观察者(observer)模式 72 第10章 调停者(mediator)模式 85 第11章 代理(proxy)模式 97 第12章 职责链(chain of responsibility)模式 115 第13章 享元(flyweight)模式 122 第14章 构造型模式介绍 130 第15章 ...

    33种JAVA设计模式DEMO

    观察者模式(Observer Pattern) 状态模式(State Pattern) 空对象模式(Null Object Pattern) 策略模式(Strategy Pattern) 模板模式(Template Pattern) 访问者模式(Visitor Pattern) 4 J2EE 模式 这些设计...

    Java设计模式之观察者模式(Observer模式)介绍

    主要介绍了Java设计模式之观察者模式(Observer模式)介绍,Java深入到一定程度,就不可避免的碰到设计模式(design pattern)这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解,需要的朋友可以...

    观察者模式(Observer)原理图

    观察者模式(Observer Pattern)是一种对象行为型设计模式,它定义了对象之间的一对多依赖关系。 当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式通常用于实现分布式事件处理系统...

    面向对象初学者必须掌握的几种设计模式

    观察者模式 Observer:Swing中的事件模型 工厂模式 Factory:在JDK中遍地都是,比如JDBC、JNDI等,是学习Spring的基础 命令模式 Command:Struts框架的基石 单例模式 Singleton:最简单的设计模式,大量...

    详解Java编程的Observer观察者设计模式

    主要介绍了Java编程的Observer观察者设计模式,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象,需要的朋友可以参考下

    [行为模式]head first 设计模式之观察者模式(observer)

    NULL 博文链接:https://jacky-dai.iteye.com/blog/1132063

    java设计模式教程+源代码

    AbstractFactory ( 抽象工厂 ) FactoryMethod ( 工厂方法 ) Singleton ( 单态模式 ) ...Observer ( 观察者模式 ) State ( 状态模式 ) Strategy ( 策略模式 ) TemplateMethod ( 模板方法 ) Visitor ( 访问者模式 )

    java设计模式期末考试选择题100道

    适合Java设计模式期末考试选择题复习,形式如下: 10.(单选题)Facade(外观)模式的意图是 正确答案: A A.希望简化现有系统的使用方法,你需要定义自己的接口 B.将一个无法控制的现有对象与一个特定借口相匹配。 C....

    23种设计模式的java源代码

    里面包含了23中设计模式源代码,其中包括工厂模式(Factory)、单例(Singleton)、观察者模式(Observer)、适配器模式(Adapter)、Template模式、Decorate模式、proxy模式等 这些代码对于初学者看起来稍微复杂一些,我...

    用Java实现23种设计模式

    用Java实现23种设计模式 1. 创建型模式 工厂模式(Factory Pattern) 抽象工厂模式(Abstract Factory Pattern) 单例模式(Singleton Pattern) 建造者模式(Builder Pattern) 原型模式(Prototype Pattern)...

    java观察者模式.doc

    在设计一组依赖的对象与它们所依赖的对象之间一致(同步)的交流模型时,观察者模式(Observer Pattern)很有用。它可以使依赖对象的状态与它们所依赖的对象的状态保持同步。这组依赖的对象指的是观察者(Observer)...

Global site tag (gtag.js) - Google Analytics