观察者模式(Observer)

本文详细介绍了观察者模式的原理及应用场景,通过实例演示了如何利用该模式实现对象间的依赖关系,包括自定义实现和使用Java内置类两种方式。

    观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知你。其实,简单来讲就一句话:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系。这里把RSS订阅改称为“主题”(Subject),订阅者改称为“观察者”(Observer)。

    看实现代码:

    定义观察者接口:
public interface IObserver {
	void update();
}
    观察者实现类:
public class ObserverAImpl implements IObserver {
	@Override
	public void update() {
		System.out.println("ObserverA  update()! ");
	}
}
public class ObserverBImpl implements IObserver {
	@Override
	public void update() {
		System.out.println("ObserverB  update()! ");
	}
}
    定义主题接口:
public interface ISubject {
	void addObserver(IObserver o);

	void removeObserver(IObserver o);

	void notifyObserver();
}
    主题实现类:
public class RssSubjectImpl implements ISubject {
	private ArrayList observerList;

	public RssSubjectImpl() {
		observerList = new ArrayList<IObserver>();
	}

	@Override
	public void addObserver(IObserver o) {
		observerList.add(o);
	}

	@Override
	public void removeObserver(IObserver o) {
		int i = observerList.indexOf(o);
		if (i >= 0) {
			observerList.remove(i);
		}
	}

	@Override
	public void notifyObserver() {
		for (int i = 0; i < observerList.size(); i++) {
			IObserver observer = (IObserver) observerList.get(i);
			observer.update();
		}
	}

	public void change() {
		notifyObserver();
	}
}
    测试:
public static void main(String[] args) {
		RssSubjectImpl subject = new RssSubjectImpl();
		IObserver observerA = new ObserverAImpl();
		IObserver observerB = new ObserverBImpl();

		subject.addObserver(observerA);
		subject.change();
		
		System.out.println();
		
		subject.addObserver(observerB);
		subject.change();
	}
    运行结果:
ObserverA  update()! 

ObserverA  update()! 
ObserverB  update()!

     每次主题调用change()时,注册在该主题的观察者就会有相应的动作。可不可以这样呢,当主题某一数据发生改变时,不用显式地调用change(),关注该主题的观察者就能接收到数据的变化。

    如下示例:

public interface IObserver {
	void update(ISubject subject);
}

public class ObserverAImpl implements IObserver {
	private ISubject subject;

	@Override
	public void update(ISubject subject) {
		if (subject instanceof RssSubjectImpl) {
			RssSubjectImpl weatherSubject = (RssSubjectImpl) subject;
			System.out.println("ObserverA  update()! getA()="
					+ weatherSubject.getA());
			System.out.println("ObserverA  update()! getB()="
					+ weatherSubject.getB());
		}
	}
}

public class ObserverBImpl implements IObserver {
	private ISubject subject;

	@Override
	public void update(ISubject subject) {
		if (subject instanceof RssSubjectImpl) {
			RssSubjectImpl weatherSubject = (RssSubjectImpl) subject;
			System.out.println("ObserverB  update()! getA()="
					+ weatherSubject.getA());
			System.out.println("ObserverB  update()! getB()="
					+ weatherSubject.getB());
		}
	}
}

public interface ISubject {
	void addObserver(IObserver o);

	void removeObserver(IObserver o);

	void notifyObserver();
}

public class RssSubjectImpl implements ISubject {
	private ArrayList observerList;
	private int a;
	private int b;
	private boolean hasChanged = false;

	public RssSubjectImpl() {
		observerList = new ArrayList<IObserver>();
	}

	@Override
	public void addObserver(IObserver o) {
		observerList.add(o);
	}

	@Override
	public void removeObserver(IObserver o) {
		observerList.remove(o);
	}

	@Override
	public void notifyObserver() {
		for (int i = 0; i < observerList.size(); i++) {
			IObserver observer = (IObserver) observerList.get(i);
			observer.update(this);
		}
	}

	public void setA(int a) {
		this.a = a;
		hasChanged = true;
		change();
	}

	public void setB(int b) {
		this.b = b;
		hasChanged = true;
		change();
	}

	public int getA() {
		return this.a;
	}

	public int getB() {
		return this.b;
	}

	public void change() {
		if (hasChanged) {
			notifyObserver();
		}
		hasChanged = false;
	}
}
     测试:
	public static void main(String[] args) {
		RssSubjectImpl subject = new RssSubjectImpl();
		IObserver observerA = new ObserverAImpl();
		IObserver observerB = new ObserverBImpl();
		
		subject.addObserver(observerA);
		subject.setA(8);
		System.out.println();
		subject.addObserver(observerB);
		subject.setB(8);
		System.out.println("*********************");
		subject.setA(7);
	}
     运行结果:
ObserverA  update()! getA()=8
ObserverA  update()! getB()=0

ObserverA  update()! getA()=8
ObserverA  update()! getB()=8
ObserverB  update()! getA()=8
ObserverB  update()! getB()=8
*********************
ObserverA  update()! getA()=7
ObserverA  update()! getB()=8
ObserverB  update()! getA()=7
ObserverB  update()! getB()=8

     Java也内置了实现观察者模式的类与接口,java.util.Observable类,Observable是一个抽象的主题对象。如果它被改变了,它必须调用setChanged()方法。当它准备通知它的改变时,它必须调用notifyObservers()方法,这导致了在观测对象中对update()方法的调用。如果在调用notifyObservers()方法之前没有调用setChanged()方法,就不会有什么动作发生。java.util.Observer接口。此接口中只有一个方法:void update(Observable o, Object arg) ,这个方法在被观察对象(Observable类)的notifyObservers()方法中被调用。
    示例:
public class Subject extends Observable {
	public void countdown(int number) {
		// 设置改变变量
		
		setChanged();
		// 通知所有观察者,将number作为参数信息传递给观察者
		notifyObservers(number);
	}
}

public class ObserverA implements Observer {
	public void update(Observable o, java.lang.Object arg) {
		// TODO Auto-generated method stub
		System.out.println("ObserverA   "+arg);
	}
}

public class ObserverB implements Observer {
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		System.out.println("ObserverB   " + arg);
	}
}

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Subject subject = new Subject();
		subject.addObserver(new ObserverA());
		subject.addObserver(new ObserverB());
		
		subject.countdown(7);
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值