`
duolaaqian
  • 浏览: 14101 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

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

阅读更多

 

/**
 * 模拟 观察者模式
 * 场景:
 * 	小孩睡觉,家长工作
 * 	小孩醒来,家长喂饭
 */
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);
		}
	}
}

 运行结果:

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

 

分享到:
评论

相关推荐

    设计模式-Java语言中的应用(pdf)

    《设计模式——Java语言中的应用》是一本专为Java开发者深入理解面向对象设计而编写的经典书籍。...无论是初级开发者还是经验丰富的程序员,都应该不断探索和实践设计模式,以提升自己的专业技能。

    研磨设计模式-part2

    第12章 观察者模式(Observer) 第13章 命令模式(Command) 第14章 迭代器模式(Iterator) 第15章 组合模式(Composite) 第16章 模板方法模式(Template Method) 第17章 策略模式(Strategy) 第18章 状态模式...

    研磨设计模式-part4

    第12章 观察者模式(Observer) 第13章 命令模式(Command) 第14章 迭代器模式(Iterator) 第15章 组合模式(Composite) 第16章 模板方法模式(Template Method) 第17章 策略模式(Strategy) 第18章 状态模式...

    研磨设计模式-part3

    第12章 观察者模式(Observer) 第13章 命令模式(Command) 第14章 迭代器模式(Iterator) 第15章 组合模式(Composite) 第16章 模板方法模式(Template Method) 第17章 策略模式(Strategy) 第18章 状态模式...

    Java设计模式之禅

    4. 观察者模式(Observer Pattern):定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知。 5. 状态模式(State Pattern):允许一个对象在其内部状态改变时改变它的...

    研磨设计模式(完整带书签).part2.pdf

    第12章 观察者模式(Observer) 第13章 命令模式(Command) 第14章 迭代器模式(Iterator) 第15章 组合模式(Composite) 第16章 模板方法模式(Template Method) 第17章 策略模式(Strategy) 第18章 状态模式...

    JS设计模式与开发实践

    - **观察者模式**:定义对象间的一种一对多依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。 #### 六、面向对象设计原则 - **单一职责原则**:一个类应该只有一个引起它变化的...

    java设计模式的 3本书 1 ppt

    Gang of Four)的经典著作《设计模式:可复用面向对象软件的基础》中的分类,包括创建型模式(如工厂模式、抽象工厂模式、单例模式等)、结构型模式(如适配器模式、桥接模式、装饰模式等)和行为型模式(如策略模式...

    C/C++设计模式基础教程

    - **观察者模式**:当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 - **迭代器模式**:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。 - **访问者...

    java23种设计模式详细讲解

    包括解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式、责任链模式。 4. 设计原则 设计原则是设计模式的基础,它包括六大原则:单一职责原则、开闭原则...

    研磨设计模式PDF

    观察者模式(Observer)定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新;状态模式(State)允许一个对象在其内部状态改变时改变其行为;策略模式...

    java开发设计模式

    - 观察者模式(Observer Pattern) - 状态模式(State Pattern) - 策略模式(Strategy Pattern) - 模板方法模式(Template Method Pattern) - 访问者模式(Visitor Pattern) 除了这23种经典设计模式外,...

    研磨设计模式(完整带书签).part1.pdf

    第12章 观察者模式(Observer) 第13章 命令模式(Command) 第14章 迭代器模式(Iterator) 第15章 组合模式(Composite) 第16章 模板方法模式(Template Method) 第17章 策略模式(Strategy) 第18章 状态模式...

    数据结构与设计模式电子书籍

    这本书可能涵盖单例模式、工厂模式、观察者模式、装饰器模式等,这些都是在大型项目中常见的设计模式。"IT十年经典书系列英文版-Design_Patterns-Elements_of_Reusable_Object-Oriented_Software.pdf"则是经典的...

Global site tag (gtag.js) - Google Analytics