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 设计模式之《观察者模式》》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Ethnography and Virtual Worlds

Ethnography and Virtual Worlds

Tom Boellstorff、Bonnie Nardi、Celia Pearce、T. L. Taylor / Princeton University Press / 2012-9-16 / GBP 21.00

"Ethnography and Virtual Worlds" is the only book of its kind - a concise, comprehensive, and practical guide for students, teachers, designers, and scholars interested in using ethnographic methods t......一起来看看 《Ethnography and Virtual Worlds》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具