观察者设计模式

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

在这个定义当中,首先第一个关键词是依赖关系,这是类与类之间关系的一种,依赖是指一个类依赖另一个类,一般是通过形参的方式传递对象在方法中,其二:是怎么做到目标对象通知后观察者自动更新呢?  其实做到这点也不难,就是该类有自动更新方法的所属对象即可做到自动更新,


观察者模块角色包括如下:

Subject:目标

ConcreteSubject:具体目标

Observer:观察者

ConcreteObserver:具体观察者


这样讲可能大家看的不太明白,打个比方:假如猫是老鼠和够的观察对象,老鼠和狗是观察者,而猫是被观察者也就是目标对象,目标对象就一个,但是观察者就可以有多个,猫叫老鼠跑,猫叫狗跑,现在使用观察者模式来写出该代码.


Subject.java 目标对象抽象类,当然也可以写成接口

<pre class="java" name="code">/**
 * 被观察的目标 有添加 和删除  通知的共有方法
 * @author carpool
 */
public interface Subject {
		//注册或者叫添加观察者
		void  resgister(Observer observer);
		//删除观察者
		void  delete(Observer observer);
		//具体目标的行为属性
		void cry();
}

 

具体的目标对象,Cat.java

public class Cat implements Subject {
	/**
	 * 对外部类提供注册观察者的方法
	 */
	List<Observer> list = new ArrayList<Observer>();
	@Override
	public void resgister(Observer observer) {
		list.add(observer);
	}
	@Override
	public void delete(Observer observer) {
		list.remove(observer);
	}
	/**
	 * 当猫叫的时候通知 所注册的观察者也就是
	 * 老鼠和狗要跑
	 */
	@Override
	public void cry() {
		for(Observer observer:list){
			observer.response();
		}
	}
}


Observer.java  观察者抽象类

public interface Observer {
	void response();//定义观察者自动更新的方法
}

Dog.java 具体的观察者

public class Dog implements Observer {
	@Override
	public void response() {
		System.out.println("猫叫了   通知    狗快跑……");
	}
}

Mouse.java也是观察者之一

public class Mouse implements Observer {
	@Override
	public void response() {
		System.out.println("猫叫了   通知    老鼠快跑……");
	}
}


客户端 Client.java负责注册观察者和目标通知

public class Client {
		public static void main(String[] args) {
			  Cat cat = new Cat();//创建目标对象
			  Dog dog = new Dog();//创建观察者
			  Mouse mouse = new Mouse();//创建观察者
			  cat.resgister(mouse);//注册观察者到目标对象中,一般用集合保存注册的观察者
			  cat.resgister(dog);//注册观察者到目标对象中,一般用集合保存注册的观察者
			  cat.cry();//通知目标对象,发生该变了,然后观察者自动更新
		}
}


打印结果:

猫叫了   通知    老鼠快跑……
猫叫了   通知    狗快跑……


从打印的结果看,和注册观察者对象的顺序一致,

现在有个需求是这样的,当观察者更新的时候判断下用户的某个行为,比如目标对象是否登录了,如果目标对象登录了才更新,加了一个这样的需求,

分析:结合上面的例子看

@Override
	public void response() {
		System.out.println("猫叫了   通知    狗快跑……");
	}

这是更新的方法,但是要判断目标对象的登录是否,就必须持有目标对象才能更新,那么要么是通过参数传递进去,要么是通过构造函数实现,

一:通过构造函数方式实现:

Subject.java

/**
 * 被观察的目标 有添加 和删除  通知的共有方法
 * @author carpool
 */
public interface Subject {
		//注册或者叫添加观察者
		void  resgister(Observer observer);
		//删除观察者
		void  delete(Observer observer);
		//具体目标的行为属性
		void cry();
}


Cat.java

public class Cat implements Subject {
	/**
	 * 对外部类提供注册观察者的方法
	 */
	List<Observer> list = new ArrayList<Observer>();
	@Override
	public void resgister(Observer observer) {
		list.add(observer);
	}
	@Override
	public void delete(Observer observer) {
		list.remove(observer);
	}
	/**
	 * 当猫叫的时候通知 所注册的观察者也就是
	 * 老鼠和狗要跑
	 */
	@Override
	public void cry() {
		for(Observer observer:list){
			observer.response();
		}
	}
	/**
	 * 登陆
	 * @return
	 */
	public boolean  login(){
		return true;
	}
}

Observer.java

public interface Observer {
	void response();//定义观察者自动更新的方法
}


Dog.java

public class Dog implements Observer {
	public Cat cat;
	
	public Dog(Cat cat) {
		this.cat = cat;
	}
	@Override
	public void response() {
		if(cat.login()){
			System.out.println("猫叫了   通知    狗快跑……");
		}
	}
}

Mouse.java

public class Mouse implements Observer {
	public Cat cat;
	
	public Mouse(Cat cat) {
		this.cat = cat;
	}

	@Override
	public void response() {
		if(cat.login()){
			System.out.println("猫叫了   通知    老鼠快跑……");
		}
	}
}


Client.jav

public class Client {
		public static void main(String[] args) {
			  Cat cat = new Cat();//创建目标对象
			  Dog dog = new Dog(cat);//创建观察者
			  Mouse mouse = new Mouse(cat);//创建观察者
			  cat.resgister(mouse);//注册观察者到目标对象中,一般用集合保存注册的观察者
			  cat.resgister(dog);//注册观察者到目标对象中,一般用集合保存注册的观察者
			  cat.cry();//通知目标对象,发生该变了,然后观察者自动更新
		}
}

打印结果:

猫叫了   通知    老鼠快跑……
猫叫了   通知    狗快跑……


二:是通过形式传递方式如下:

public interface Observer {
	void response(Subject subject);//定义观察者自动更新的方法
}


但是在jdk中sun公司其实帮我们实现了观察者模式,我们只要实现其暴露出来的接口就行,


观察者模块的优点:

在于可以实现表示层和数据逻辑层的分离,并在观察目标和观察者之间建立了一个抽象的耦合,支持广播通信,


缺点:当观察者很多时,会消耗很多时间去通知观察者更新!



















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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值