`
rokily
  • 浏览: 3126 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

《head first》学习笔记之二——观察者模式

阅读更多
通俗的理解一下观察者模式:当一个受观察对象发生改变时,则观察它的所有对象都跟着更新。应用场景如,天气信息改变时,各种显示设备都跟着更新。

主要类包括:主题接口(被观察者接口)、主题类、观察者接口、观察者类。

过程中,主题(被观察者)可以采用push数据方式让观察者更新,观察者也可以采用pull数据方式更新,主要看数据的安全性问题,以及各观察者需要的数据情况。

观察者模式可以自己单独实现,也可以采用java.util.Observer接口(观察者)和java.util.Observable类(主题,被观察者)来实现,但是后者在更新个观察者时,是不分先后顺序的,而自己实现的时候可以控制这个更新顺序。

下面分别实验两种情况:

首先是自己实现,

1,下面是主题接口
package net.roky.pattern.observer.self;


public interface Subject {
	//注册增加观察者
	public void addObserver(Observer o);
	//删除观察者
	public void delObserver(Observer o);
	//修改通知观察者
	public void notifyObservers();
}

2,下面是观察者接口
package net.roky.pattern.observer.self;

public interface Observer {
	//观察者更新
	public void update(int d1, String d2);
}

3,下面是其他的一些接口,主要是观察者类实现的时候用
package net.roky.pattern.observer.self;

public interface Display {
	//屏显
	public void display();
}

4,下面是主题的实现类,即一个被观察类
package net.roky.pattern.observer.self;

import java.util.ArrayList;

public class ConcreteSubject implements Subject {
	ArrayList<Observer> arrayList;
	private int data1;
	private String data2;
	
	ConcreteSubject(){
		arrayList = new ArrayList<Observer>();
	}
	
	public void setElements(int d1, String d2){
		this.data1 = d1;
		this.data2 = d2;
		this.notifyObservers();
	}
	
	public int getData1(){
		return this.data1;
	}
	
	public String getData2(){
		return this.data2;
	}
	
	public void addObserver(Observer o) {
		// TODO 自动生成方法存根
		this.arrayList.add(o);
	}

	public void delObserver(Observer o) {
		// TODO 自动生成方法存根
		int i = this.arrayList.indexOf(o);
		if(i>=0){
			this.arrayList.remove(i);
		}
	}

	public void notifyObservers() {
		// TODO 自动生成方法存根
		for(Observer o : this.arrayList){
			o.update(this.data1, this.data2);
		}
	}

}

5,下面是其中一个观察者
package net.roky.pattern.observer.self;

public class O1 implements Observer, Display {
	private int data1;

	private String data2;
	
	O1(Subject subject){
		subject.addObserver(this);
	}

	public void update(int d1, String d2) {
		// TODO 自动生成方法存根
		this.data1 = d1;
		this.data2 = d2;
		this.display();
	}

	public void display() {
		// TODO 自动生成方法存根
		System.out.println("new data:" + " data1:" + data1 + " data2:" + data2);
	}

}

6,下面是另一个观察者
package net.roky.pattern.observer.self;

public class O2 implements Observer, Display {
	private int data1;
	
	O2(Subject subject){
		subject.addObserver(this);
	}

	public void update(int d1, String d2) {
		// TODO 自动生成方法存根
		this.data1 = d1;
		this.display();
	}

	public void display() {
		// TODO 自动生成方法存根
		System.out.println("new data:" + " data1:" + data1);
	}

}

7,测试一下
package net.roky.pattern.observer.self;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO 自动生成方法存根
		ConcreteSubject cs = new ConcreteSubject();
		new O1(cs);
		new O2(cs);
		
		cs.setElements(10, "abcdefg");
		cs.setElements(20, "hijklmn");
	}

}


整个过程很简单,扩展性很好。
上面的程序采用的是push的方式,如果想采用pull的方式,首先将观察者update方法参数改成主题接口类型,然后将主题类属性修改为public标识,之后就可以在update中强制转化类型并pull数据了。


下面是java.util.包中提供的观察者模式,需要说明的是,Observable(主题,被观察者)是一个类,而不是接口。

1,首先写一个具体的主题(被观察者),继承Observable类
package net.roky.pattern.observer;

import java.util.Observable;

public class WeatherData extends Observable {
	private float temperature;
	private float humidity;
	private float pressure;
	
	WeatherData(){
		
	}
	
	public float getTemperature(){
		return this.temperature;
	}
	
	public float getHumidity(){
		return this.humidity;
	}
	
	public float getPressure(){
		return this.pressure;
	}
	
	public void measurementsChanged(){
		super.setChanged();
		super.notifyObservers();
	}
	
	public void setMeasurements(float t, float h, float p){
		this.temperature = t;
		this.humidity = h;
		this.pressure = p;
		this.measurementsChanged();
	}
}

2,其中一个观察者
package net.roky.pattern.observer;

import java.util.Observable;
import java.util.Observer;

public class Display1 implements Observer {
	//Observable observeable;
	private float temperature;
	private float humidity;
	
	Display1(Observable observable){
		observable.addObserver(this);
	}
	
	public void update(Observable arg0, Object arg1) {
		if(arg0 instanceof WeatherData){
			WeatherData weatherData = (WeatherData) arg0;
			this.temperature = weatherData.getTemperature();
			this.humidity = weatherData.getHumidity();
			this.display();
		}
	}
	
	public void display(){
		System.out.println("display1,"+ " temperature:" + this.temperature + " ,humidity:" + this.humidity);
	}

}

3,另一个观察者
package net.roky.pattern.observer;

import java.util.Observable;
import java.util.Observer;

public class Display2 implements Observer {
	// Observable observeable;
	private float temperature;

	private float humidity;

	private float pressure;

	Display2(Observable observable) {
		observable.addObserver(this);
	}

	public void update(Observable arg0, Object arg1) {
		if (arg0 instanceof WeatherData) {
			WeatherData weatherData = (WeatherData) arg0;
			this.temperature = weatherData.getTemperature();
			this.humidity = weatherData.getHumidity();
			this.pressure = weatherData.getPressure();
			this.display();
		}
	}

	public void display() {
		System.out.println("display2," + " temperature:" + this.temperature
				+ " ,humidity:" + this.humidity + " ,pressure:" + this.pressure);
	}

}

4,测试一下
package net.roky.pattern.observer;

public class Main {
	public static void main(String[] args) {
		WeatherData weatherData = new WeatherData();
		new Display1(weatherData);
		new Display2(weatherData);

		for (int i = 1; i < 1000; i++) {
			weatherData.setMeasurements(i % 100, 2 * i, 25.3f);
		}
	}
}
分享到:
评论

相关推荐

    HeadFirst 设计模式学习笔记2--观察者模式 demo

    总的来说,HeadFirst设计模式的学习笔记2关于观察者模式的演示,旨在帮助开发者理解如何使用观察者模式来构建可扩展的系统。通过实际的代码示例,我们可以更深入地掌握这一模式,并将其应用到日常开发中,提升代码的...

    Head First 设计模式学习笔记

    ### Head First 设计模式学习笔记知识点总结 #### 1. 欢迎来到设计模式世界:设计模式入门 - **业务场景**: - **需求背景**:开发一款模拟鸭子的游戏,游戏内包含多种不同种类的鸭子,每种鸭子具有不同的外观...

    Head.First 设计模式学习笔记.pdf

    ### Head.First 设计模式学习笔记知识点总结 #### 一、设计模式概述 设计模式是一种用于解决软件设计中常见问题的标准化方法。通过采用设计模式,开发者可以提高代码的复用性、灵活性和可维护性。《Head First 设计...

    Head First 设计模式学习笔记(十四)模式的组合使用

    在《Head First 设计模式学习笔记(十四)模式的组合使用》中,作者探讨了如何在实际编程中灵活地组合多种设计模式以解决复杂问题。这篇文章可能是基于《Head First 设计模式》这本书的一个章节,该书是设计模式领域...

    HeadFirst设计模式笔记

    通过《HeadFirst设计模式笔记》的学习,你将能够掌握如何在代码中正确地应用Observer模式,提升软件的可维护性和扩展性。同时,配合源码分析,能帮助你更好地理解设计模式的实现细节,提高编程技巧和解决问题的能力...

    Head First 设计模式 扫描版

    行为型模式则关注对象间的责任分配和交互,例如策略模式(Strategy)、模板方法模式(Template Method)、观察者模式(Observer)、命令模式(Command)、迭代器模式(Iterator)、访问者模式(Visitor)、备忘录...

    观察者模式

    在Head First的观察者模式学习笔记中,我们可以深入理解这个模式的原理和应用。首先,观察者模式涉及到两个主要的角色:主题(Subject)和观察者(Observer)。主题是被观察的对象,它可以是任何具有可变状态的对象...

    head first C#学习笔记:如何创建事件

    在C#编程中,事件是实现对象间通信的重要机制,特别是在设计模式中,如观察者模式。本学习笔记将深入探讨如何在C#中创建事件,以实现一个棒球模拟系统的例子。在这个系统中,我们将关注投球手、观众和裁判的交互,当...

    Head First设计模式读书笔记-DesignPatterns.zip

    《Head First设计模式》是一本深受开发者喜爱的设计模式学习书籍,它以易懂且生动的方式介绍了23种经典设计模式。这些模式是软件工程中经过实践验证的最佳实践,旨在提高代码的可重用性、可读性和可维护性。下面,...

    head first 设计模式

    通过以上对“Head First设计模式”书中可能涉及的设计模式的介绍,我们可以看出这本书是学习面向对象设计模式的绝佳资源。无论是初学者还是有一定经验的开发人员,都能从中受益匪浅。理解并熟练运用这些模式能够帮助...

    一些非常好的文档PHP技术

    2. 设计模式:`《Head First 设计模式》代码之PHP版.txt` 提到了设计模式的概念,这是软件工程中的一种经验总结,用于解决常见的编程问题。PHP程序员可以通过学习设计模式来提升代码结构和可重用性,例如工厂模式、...

    LearningProcessForJava:Java的学习过程

    8. **设计模式**:学习常见的设计模式,如工厂模式、单例模式、观察者模式,提升代码质量和可维护性。 9. **JVM原理**:理解Java虚拟机的工作方式,包括内存管理、垃圾回收机制等。 10. **Spring框架**:掌握流行的...

Global site tag (gtag.js) - Google Analytics