设计模式之观察者模式

  观察者模式很简单,比如报纸,用户订阅就会定时给用户送,这里报纸就是主题,用户就是观察者。 观察者模式有一个主题,可以多个观察者,用户可以选择注册成为该主题的观察者,观察者也可以选择取消观察该主题。主题有内容更新就会通知每一个观察者。 

  下面就由一个比较简单地例子来介绍一下观察者模式。

  假如在动物的世界里也有报纸,报纸的名字叫做Subject,森林里有老鼠,鸭子,狗等生物,他们和谐地生活着... ...有一天,动物们发现有报纸,然后他们就纷纷注册成为Subject报纸的观察者,然后每次报纸有新版出来的时候,动物们都会收到相应的新版报纸。有一天,老鼠突然觉得这份报纸没有意思了,他就取消了对Subject报纸的关注,然后老鼠就不会再收到报纸了。(当然,如果有一天他怀念报纸的内容了,他也可以再次注册为观察者),下面是类图



上面给出了类图,下面让我们来看看具体的Java实现

Observer接口

package observersMode;

public interface Observer {
	//观察者在主题出现修改时更新
	public void update();
}

Subject主题类

package observersMode;

import java.util.ArrayList;

public class Subject {
	ArrayList<Observer> observers = null;

	public Subject() {
		observers = new ArrayList<Observer>();
	}

	public void addObserver(Observer o) {
		observers.add(o);
	}

	public void deleteObserver(Observer o) {
		for (int i = 0; i < observers.size(); ++i) {
			if (observers.get(i) == o) {
				observers.remove(i);
			}
		}
	}

	//当主题有变化时,调用modify通知所有观察者
	public void modify() {
		for (int i = 0; i < observers.size(); ++i) {
			(observers.get(i)).update();
		}
	}
}
观察者Mouse类
package observersMode;

public class Mouse implements Observer {

	private Subject subject = null;
	
	public Mouse(Subject subject){
		this.subject = subject;
	}
	
	@Override
	public void update() {
		System.out.println("I am mouse, I have received the news");
	}
	
	public void register(){
		subject.addObserver(this);
	}
	
	public void remove(){
		subject.deleteObserver(this);
	}

}
观察者Duck类
package observersMode;

public class Duck implements Observer {

private Subject subject = null;
	
	public Duck(Subject subject){
		this.subject = subject;
	}
	
	@Override
	public void update() {
		System.out.println("I am duck, I have received the news");
	}
	
	public void register(){
		subject.addObserver(this);
	}
	
	public void remove(){
		subject.deleteObserver(this);
	}

}

观察者Dog类

package observersMode;

public class Dog implements Observer {

	private Subject subject = null;

	public Dog(Subject subject) {
		this.subject = subject;
	}

	@Override
	public void update() {
		System.out.println("I am dog, I have received the news");
	}

	public void register() {
		subject.addObserver(this);
	}

	public void remove() {
		subject.deleteObserver(this);
	}

}
测试文件
package observersMode;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Subject subject = new Subject();
		Mouse mouse = new Mouse(subject);
		Duck duck = new Duck(subject);
		Dog dog = new Dog(subject);
		
		System.out.println("No observer now");
		subject.modify();
		System.out.println();
		
		System.out.println("One observer now");
		mouse.register();
		subject.modify();
		System.out.println();
		
		System.out.println("Two observer now");
		duck.register();
		subject.modify();
		System.out.println();
		
		System.out.println("Three observer now");
		dog.register();
		subject.modify();
		System.out.println();
		
		System.out.println("Two observer now");
		dog.remove();
		subject.modify();
		System.out.println();
	}

}

总结

  总的来说,观察者模式适用于一对多的情况,在做这篇博客的过程中也发现一些问题,比如观察者注册register和取消观察remove是高度重复的,但是java7暂时不支持在接口里写具体的实现,所以也没办法,听说java8可以做到这些,这些大家可以去试一下。也许有人会说那么为什么不写成虚类呢?其实如果写成虚类,确实可以达到效果,但是就违反了设计原则少用继承了。














  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值