java设计模式--观察者模式(对象行为型)

1.概述

        有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

       通常来说,当某个对象的状态发生改变时,你仍然需要对象之间能互相通信。但是出于各种原因,你也许并不愿意因为代码环境的改变而对代码做大的修改。也许,你只想根据你的具体应用环境而改进通信代码。或者,你只想简单的重新构造通信代码来避免类和类之间的相互依赖与相互从属。

2.问题

      当一个对象的状态发生改变时,你如何通知其他对象?

3.解决方案

     观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。

    观察者模式允许一个对象关注其他对象的状态,并且,观察者模式还为被观察者提供了一种结构,或者说是一个主体和一个客体。主体,也就是被观察者,可以用来联系所有的观测它的观察者。客体,也就是观察者,用来接受主体状态的改变观察就是一个可被观察的类(也就是主题)与一个或多个观察它的类(也就是客体)的协作。不论什么时候,当被观察对象的状态变化时,所有注册过的观察者都会得到通知。

    将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,因为这样降低了它们的可重用性。

4.涉及到的角色

    Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。

    ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。

    Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。

    ConcrereObserver:具体观察者,是实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

4.适用性

    在以下任一情况下可以使用观察者模式:

    1)当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。

    2)当对一个对象的改变需要同时改变其它对象 , 而不知道具体有多少对象有待改变。

3)当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之 , 你不希望这些对象是紧密耦合的。

5.结构


6实例代码:

抽象被观察者(通知者)

package com.observer;
/**
* @author lxp
*
* @TODO 
* 
*/
//定义抽象被观察者(通知者)类
public  abstract class Subject {
	//增加
	public abstract void Attach(Observer observer);
	//移除
	public abstract void Detach(Observer observer);
	//通知
	public abstract void Notify();
}

抽象观察者类:

package com.observer;
/**
* @author lxp
*
* @TODO 
* 
*/
//定义抽象观察者类
public abstract class Observer {
	//观察者更新状态
	public abstract void Update();
}

具体被观察者类:

package com.observer;

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

/**
* @author lxp
*
* @TODO 
* 
*/
//定义具体被观察者(通知者)类
public class ConcreteSubject extends Subject {
	
	//定义集合存储观察者
	List<Observer> list=new ArrayList<Observer>();
	
	//增加观察者
	@Override
	public void Attach(Observer observer) {
		// TODO Auto-generated method stub
		list.add(observer);
	}

	@Override
	public void Detach(Observer observer) {
		// TODO Auto-generated method stub
		list.add(observer);
	}

	@Override
	public void Notify() {
		// TODO Auto-generated method stub
		//遍历集合观察者对象
		for(Observer observer:list){
			observer.Update();
		}
	}
}

具体观察者类:

package com.observer;
/**
* @author lxp
*
* @TODO 
* 
*/
//定义具体的观察者
public class ConcreteObserver  extends Observer{

	@Override
	public void Update() {
		// TODO Auto-generated method stub
		System.out.println("被观察者状态改变,立即更新状态");
	}
}

测试类:

package com.observer;
/**
* @author lxp
*
* @TODO 
* 
*/
//测试类
public class ObserverDemo {
	public static void main(String[] args) {
		//创建被观察者对象
		ConcreteSubject csb=new ConcreteSubject();
		//创建观察者对象
		ConcreteObserver cob=new ConcreteObserver();
		
		//将观察者添加到被观察者的通知名单内
		csb.Attach(cob);
		
		//被观察者发出通知,观察者接受通知更新状态
	    csb.Notify();
	}
}

试验结果:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值