[初级]设计模式--观察者模式

/**
 * 模拟 观察者模式
 * 场景:
 * 	小孩睡觉,家长工作
 * 	小孩醒来,家长喂饭
 */
public class ObserverDemo01 {
	public static void main(String[] args) throws InterruptedException {
		MyBaby b = new MyBaby();
		MyParent p1 = new MyParent("爸爸");
		MyParent p2 = new MyParent("妈妈");
		MyParent p3 = new MyParent("姥姥");
		MyParent p4 = new MyParent("奶奶");
		b.addObserver(p1);
		b.addObserver(p2);
		b.addObserver(p3);
		b.addObserver(p4);
		for(int i=0;i<5;i++){
			Thread.sleep(1000);
			if(b.isAwake()){
				b.sleep();
			}else{
				b.wakeUp();
			}
		}
	}
}

/**
 * 监听者
 */
interface IMyObserver{
	void update(MyObservable obs);
}
/**
 * 被监听者
 */
class MyObservable{
	protected List<IMyObserver> list = new ArrayList<IMyObserver>();
	
	public void addObserver(IMyObserver obs){
		list.add(obs);
	}
	public void removeObserver(IMyObserver obs){
		list.add(obs);
	}
	public void notifyAllObservers(){
		for (IMyObserver obs : list) {
			obs.update(this);
		}
	}
}
/**
 * 以下为监听者、被监听者实例
 */
class MyBaby extends MyObservable{
	private boolean isAwake = false;
	public boolean isAwake(){
		return this.isAwake;
	}
	public void wakeUp(){
		System.out.println("baby醒了");
		this.isAwake = true;
		notifyAllObservers();
	}
	public void sleep(){
		System.out.println("baby睡了");
		this.isAwake = false;
		notifyAllObservers();
	}
}
class MyParent implements IMyObserver{
	private String name;
	public MyParent(String name){
		this.name = name;
	}
	@Override
	public void update(MyObservable obs) {
		if( ((MyBaby)obs).isAwake() ){
			System.out.println("["+name+"]来喂饭");
		}else{
			System.out.println("["+name+"]去工作");
		}
	}
}

 运行结果:

baby醒了
[爸爸]来喂饭
[妈妈]来喂饭
[姥姥]来喂饭
[奶奶]来喂饭
baby睡了
[爸爸]去工作
[妈妈]去工作
[姥姥]去工作
[奶奶]去工作
baby醒了
[爸爸]来喂饭
[妈妈]来喂饭
[姥姥]来喂饭
[奶奶]来喂饭
baby睡了
[爸爸]去工作
[妈妈]去工作
[姥姥]去工作
[奶奶]去工作
baby醒了
[爸爸]来喂饭
[妈妈]来喂饭
[姥姥]来喂饭
[奶奶]来喂饭
/**
 * 观察者模式(JDK提供了相应的工具类)
 * 
 * 	1、创建被观察者(baby)继承 java.util.Observable
 * 		在需要观察的动作(方法)完成后调用setChanged()方法和notifyObservers()方法通知观察者
 * 	2、创建观察者(parent)继承 java.util.Observer 重写 update() 方法
 * 	3、创建双方实例并将 观察者 注册到 被观察者 中(addObserver()方法)
 * 
 * 	实现观察/广播效果,避免了使用线程实现带来的大量开销
 * 	观察者/被观察者之间的关系也容易维护
 * 
 * 注意:
 * 	1、观察者实例销毁前要通过deleteObserver()方法从监听列表中删除掉
 * 		否则对象之间依然会保持引用关系 对象未销毁 广播依然有效
 * 	2、避免循环依赖(死循环)
 * 	3、多线程下要小心
 * 
 * 应用场景:
 * 	网络编程、AWT、Android
 */
public class ObserverDemo02 {
	public static void main(String[] args) throws InterruptedException {
		Baby b = new Baby();
		Parent p1 = new Parent("爸爸");
		Parent p2 = new Parent("妈妈");
		Parent p3 = new Parent("姥姥");
		Parent p4 = new Parent("奶奶");
		b.addObserver(p1);
		b.addObserver(p2);
		b.addObserver(p3);
		b.addObserver(p4);
		for(int i=0;i<5;i++){
			Thread.sleep(1000);
			if(b.isAwake()){
				b.sleep();
			}else{
				b.wakeUp();
			}
		}
	}
}
class Baby extends Observable{
	private boolean isAwake = false;
	public boolean isAwake(){
		return this.isAwake;
	}
	public void wakeUp(){
		System.out.println("baby醒了");
		this.isAwake = true;
		setChanged();
		notifyObservers();
	}
	public void sleep(){
		System.out.println("baby睡了");
		this.isAwake = false;
		setChanged();
		notifyObservers();
	}
}
class Parent implements Observer{
	private String name;
	public Parent(String name){
		this.name = name;
	}
	@Override
	public void update(Observable o, Object arg) {
		if( ((Baby)o).isAwake() ){
			System.out.println("["+name+"]来喂饭");
		}else{
			System.out.println("["+name+"]去工作");
		}
	}
}

运行结果(同上):

baby醒了
[奶奶]来喂饭
[姥姥]来喂饭
[妈妈]来喂饭
[爸爸]来喂饭
baby睡了
[奶奶]去工作
[姥姥]去工作
[妈妈]去工作
[爸爸]去工作
baby醒了
[奶奶]来喂饭
[姥姥]来喂饭
[妈妈]来喂饭
[爸爸]来喂饭
baby睡了
[奶奶]去工作
[姥姥]去工作
[妈妈]去工作
[爸爸]去工作
baby醒了
[奶奶]来喂饭
[姥姥]来喂饭
[妈妈]来喂饭
[爸爸]来喂饭

  

/**
 * 妈妈,他拿咱裤子了
 * 谁呀
 * 逗你玩
 */
public class ObserverDemo03 {
	public static void main(String[] args) throws InterruptedException {
		String[] arr = {"褂子","裤子","褥单子"};
		YiJia yijia = new YiJia(arr);
		XiaoTou dnw = new XiaoTou("逗你玩",yijia);
		XiaoHu hu = new XiaoHu();
		yijia.addObserver(hu);
		for(int i=0;i<arr.length;i++){
			dnw.tou();
			Thread.sleep(1000);
		}
	}
}
/**
 * 晾衣架
 */
class YiJia extends Observable{
	private int initSize;
	private String[] arr;
	public YiJia(String[] arr){
		this.arr = arr;
		this.initSize = arr.length;
	}
	public int getInitSize(){
		return initSize;
	}
	public void get(XiaoTou xt){
		int index = arr.length-1;
		String oldVal = arr[index];
		System.out.println("====["+xt.name+"]拿走了["+oldVal+"]");
		xt.hold = oldVal;
		String[] newArr = new String[index];
		System.arraycopy(arr, 0, newArr, 0, index);
		arr = newArr;
		setChanged();
		notifyObservers(xt);
	}
}
/**
 * 小偷(逗你玩)
 */
class XiaoTou{
	private YiJia yijia;
	String name;
	String hold;
	public XiaoTou(String name, YiJia yijia){
		this.name = name;
		this.yijia = yijia;
	}
	public void tou(){
		yijia.get(this);
	}
}
/**
 * 小虎
 */
class XiaoHu implements Observer{
	@Override
	public void update(Observable o, Object arg) {
		if(arg instanceof XiaoTou){
			System.out.println("妈妈,他那咱*"+((XiaoTou)arg).hold+"*了!");
			System.out.println("谁呀?");
			System.out.println(((XiaoTou)arg).name);
		}
	}
}

 运行结果:

====[逗你玩]拿走了[褥单子]
妈妈,他那咱*褥单子*了!
谁呀?
逗你玩
====[逗你玩]拿走了[裤子]
妈妈,他那咱*裤子*了!
谁呀?
逗你玩
====[逗你玩]拿走了[褂子]
妈妈,他那咱*褂子*了!
谁呀?
逗你玩

猜你喜欢

转载自duolaaqian.iteye.com/blog/2250908