Java 设计模式之《观察者模式》

栏目: Java · 发布时间: 6年前

内容简介:很久之前,自己也曾看过一些设计模式的内容,最近在做一些程序代码设计的时,发现忘得差不多了,很多模式也只是有大致影响,决定重新将一些常用的模式复习一下。今天一个模式观察者模式。观察者模式属于行为模式中的一种;观察者模式定对象一个一对多的依赖关系,让多个观察者对象同时监听同一个主题对象,主题对象在状态发生改变时,通知所有观察者对象使他们能够更新自己。上面是观察者模式设计类图

很久之前,自己也曾看过一些 设计模式 的内容,最近在做一些程序代码设计的时,发现忘得差不多了,很多模式也只是有大致影响,决定重新将一些常用的模式复习一下。今天一个模式观察者模式。

观察者模式

观察者模式属于行为模式中的一种;观察者模式定对象一个一对多的依赖关系,让多个观察者对象同时监听同一个主题对象,主题对象在状态发生改变时,通知所有观察者对象使他们能够更新自己。

Java 设计模式之《观察者模式》

上面是观察者模式设计类图

  • subject:它是抽象主题的接口,对象通过此接口将自己注册为观察者,或将自己从观察中者删除

  • ConcreteSubject:一个实现主题接口的具体主题,除了实现注册和删除的方法外,它还有一个change方法,用来在状态改变时通知所有观察者

  • Observer:观察者接口,所有具体的观察者都实现此接口

  • ConcreteObserver:具体的观察者

package com.mtx.demo.observer;

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

public abstract class Subject {

	// 保存注册的观察者对象
	private List<Observer> list = new ArrayList<Observer>();

	// 注册观察者对象
	public void attach(Observer observer) {
		list.add(observer);
		System.out.println("添加新的观察者");
	}

	// 删除观察者对象
	public void detach(Observer observer) {
		list.remove(observer);
		System.out.println("删除一个观察者");
	}

	// 通知所有注册的观察者对象
	public void nodifyObservers(String newState) {
		for (Observer observer : list) {
			observer.update(newState);
		}
	}
}
复制代码

一个具体主题

package com.mtx.demo.observer;

public class ConcreteSubject extends Subject {

	private String state;

	public String getState() {
		return state;
	}

	// 状态发生改变,通知各个观察者
	public void change(String newState) {
		state = newState;
		this.nodifyObservers(state);
	}
}
复制代码

抽象的观察者

package com.mtx.demo.observer;

public interface Observer {
	// 更新接口
	public void update(String state);
}
复制代码

一个具体观察者

package com.mtx.demo.observer;

public class ConcreteObserver implements Observer {

	private String observerState;

	@Override
	public void update(String state) {
		observerState = state;
		System.out.println("观察者状态跟新了:" + observerState);
	}
}
复制代码

客户端中,我们创建一个具体主题对象,在创建一个观察者对象,之后将观察注册到主题对象像上,这样当主题对象的状态改变时,所有的观察者对象都会收到通知,改变自己的状态。

package com.mtx.demo.observer;

public class Client {

	public static void main(String[] args) {
		// 创建主题对象
		ConcreteSubject subject = new ConcreteSubject();
		// 创建观察者对象
		Observer observer = new ConcreteObserver();
		// 将观察者对象登记到主题对象上
		subject.attach(observer);
		// 改变主题对象的状态
		subject.change("有新的技术博客了");
	}

}
复制代码

运行代码结果如下

Java 设计模式之《观察者模式》

问题

  • 观察者模式中一对多是如何体现的

主题是一个具有状态的对象,而多个观察者可以使用这个主题的状态,多个观察者依赖主题对象来告诉他们这些状态何时改变,这就产生了一个主题对应多观察者的关系

  • 观察者模式是松如何做到耦合的

主题只知道观察者实现了某一个接口(Observer接口),主题不用知道观察者具体是谁,做了哪些操作等,任何时候我们都可以添加新的观察者,那是因为主题唯一依赖的是一个观察者的Observer接口的对象列表,因此我们可以随时添加观察者,有新的主题出现时主题代码不用修改。

推模型和拉模型。

  • 推模型:主题对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据,刚才上面的例子就是一个推模型。

推模型会是观察者难以复用,因为每个观察者的updata方法的参数可能不同,数据量非常大的时候推模型不适合

  • 拉模型:主题对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当于是观察者从主题对象中拉数据。一般这种模型的实现中,会把主题对象自身通过update()方法传递给观察者,这样在观察者需要获取数据的时候,就可以通过这个引用来获取了。

另外 Java 语言提供的对观察者模式的支持,在java.util包中,提供了一个Observable类以及一个Observer接口

  • 优点:

1.在观察者和被观察者之间建立一个抽象的耦合;

2.支持广播通信

  • 缺点:

1.如果一个被观察者对象有很多观察者,将所有观察者通知到会花费很多时间;

2.如果在被观察者之间有循环依赖,被观察者会触发他们之间的循环调用,导致系统崩溃;

3.观察者没有相应的方式使其知道所观察的对象时怎么发生变化的。

参考:Head First 设计模式


以上所述就是小编给大家介绍的《Java 设计模式之《观察者模式》》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

期货趋势程序化交易方法

期货趋势程序化交易方法

马文胜 编 / 中国财政经济 / 2008-1 / 42.00元

《期货趋势程序化交易方法》可作为学习期货行业的教程。中国期货行业非常重视期货人才队伍的建设,无论是在抓紧推进期货分析师的认证体系建设、提升期货分析师的执业水平上,还是在专业人才的后续教育上。 要想在期货市场上长期生存并保持稳定的获利,必须在充分认识市场的基础上,建立一个有效的系统化的手段和程序化的方法,把一切的复杂性和不确定性全部加以量化,使所有的交易有序而直观,才能最终达到低风险、低回报。一起来看看 《期货趋势程序化交易方法》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换