小孩睡觉模拟(Observer设计模式)

一小孩睡觉,醒了要东西吃,父亲就得喂他东西。

典型的模拟题。代码如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Child{
	
	private boolean wakenUp;
	
	public Child() {
		
		try {
			System.out.println("Child sleep.");
		
			//用新的线程模拟小孩睡觉,防止在构造函数阻塞了
			ExecutorService executor=Executors.newSingleThreadExecutor();
			executor.execute(new Runnable(){
				
				public void run(){
					
					try {
						Thread.sleep(10000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					wakeup();
				}
			});
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void wakeup() {
		
		System.out.println("Child wake up.");
		wakenUp = true;
	}

	public boolean isWakenUp() {
		
		return wakenUp;
	}
}
class Dad implements Runnable{
	
	private Child child = null;
	
	public Dad(Child child) {
		
		this.child = child;
	}
	public void run() {
		
		while(!this.child.isWakenUp()) {
			
			try {
				System.out.println("Dad wait.");
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		feed();
	}
	
	public void feed() {
		
		System.out.println("feed child.");
	}
}
public class Main {

	public static void main(String[] args){
		
		Child child = new Child();
		new Thread(new Dad(child)).start();
	}
}

这种题目不幼稚,就算开发多年的人都该时不时的思考一下。能做山珍海味的固然是好厨师,但能把家常的萝卜白菜给炖出了美妙的味道,那才是高手。

输出为:

Child sleep.
Dad wait.
Dad wait.
Dad wait.
Dad wait.
Dad wait.
Dad wait.
Dad wait.
Dad wait.
Dad wait.
Dad wait.
Child wake up.
feed child.

但是,每隔一秒让父亲监测显然是不够人性化的,那么就需要将主动变为被动。在Child类中加入对Dad类的引用,从而使得在孩子醒时,主动调用Dad类的feed方法。

代码如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Child{
	
	private Dad dad=new Dad();
	public Child(){
		
		System.out.println("Child sleep.");
		
		ExecutorService exeService = Executors.newSingleThreadExecutor();
		exeService.execute(new Runnable(){
			
			public void run() {
				
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				wakeup();
				
				//化主动监测为被动
				dad.feed();
			}
		});
	}
	public void wakeup(){
		
		System.out.println("Child wake up.");
	}
}
class Dad{
	
	public void feed() {
		
		System.out.println("Feed child.");
	}
}
public class Main{
	
	public static void main(String[] args){
		
		Child child=new Child();
	}
}

输出为:

Child sleep.
Child wake up.
Feed child.

第三版更灵活的程序,有事件,和不同的观察者。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class WakeupEvent {
	
	private long time;
	private String location;
	private Child source;
	
	public WakeupEvent(long time,String location,Child source){
		
		this.time = time;
		this.location = location;
		this.source = source;
	}

	public long getTime() {
		return time;
	}

	public void setTime(long time) {
		this.time = time;
	}

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}

	public Child getSource() {
		return source;
	}

	public void setSource(Child source) {
		this.source = source;
	}
}
class Child{
	
	private Family family=null;
	
	public Child(Family family){
		
		this.family=family;
		System.out.println("Child sleep.");
		
		ExecutorService exeService = Executors.newSingleThreadExecutor();
		exeService.execute(new Runnable(){
			
			public void run() {
				
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				wakeup();
				
				//化主动监测为被动
				Child.this.family.wakeupAction(new WakeupEvent(System.currentTimeMillis(),"bed",Child.this));
			}
		});
	}
	public void wakeup(){
		
		System.out.println("Child wake up.");
	}
}
interface Family{
	
	public void wakeupAction(WakeupEvent wakeup);
}
class Dad implements Family{
	
	public void wakeupAction(WakeupEvent wakeup){
		
		//根据WakeupEvent的不同情况作出不同的反应
		//代码略
		System.out.println("Feed Child.");
	}
}
class GrandFather implements Family{

	@Override
	public void wakeupAction(WakeupEvent wakeup) {
		
		System.out.println("Hug child.");
	}
}
public class Main{
	
	public static void main(String[] args){
		
		Child child=new Child(new GrandFather());
	}
}

如果有多个观察者,可以用List的方式,上面的程序只有1个观察者。

输出为:

Child sleep.
Child wake up.
Hug child.

多个观察者的代码如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.*;
class WakeupEvent {
	
	private long time;
	private String location;
	private Child source;
	
	public WakeupEvent(long time,String location,Child source){
		
		this.time = time;
		this.location = location;
		this.source = source;
	}

	public long getTime() {
		return time;
	}

	public void setTime(long time) {
		this.time = time;
	}

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}

	public Child getSource() {
		return source;
	}

	public void setSource(Child source) {
		this.source = source;
	}
}
class Child{
	
	private List<Family> familyList=null;
	
	public Child(List<Family> list){
		
		this.familyList=list;
		System.out.println("Child sleep.");
		
		ExecutorService exeService = Executors.newSingleThreadExecutor();
		exeService.execute(new Runnable(){
			
			public void run() {
				
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				wakeup();
				
				//化主动监测为被动
				for(int i=0;i<familyList.size();i++)
				{
					familyList.get(i).wakeupAction(new WakeupEvent(System.currentTimeMillis(),"bed",Child.this));
				}
			}
		});
	}
	public void wakeup(){
		
		System.out.println("Child wake up.");
	}
}
interface Family{
	
	public void wakeupAction(WakeupEvent wakeup);
}
class Dad implements Family{
	
	public void wakeupAction(WakeupEvent wakeup){
		
		//根据WakeupEvent的不同情况作出不同的反应
		//代码略
		System.out.println("Feed Child.");
	}
}
class GrandFather implements Family{

	@Override
	public void wakeupAction(WakeupEvent wakeup) {
		
		System.out.println("Hug child.");
	}
}
public class Main{
	
	public static void main(String[] args){
		
		List<Family> list=new ArrayList<Family>();
		list.add(new Dad());
		list.add(new GrandFather());
		Child child=new Child(list);
	}
}

输出为:

Child sleep.
Child wake up.
Feed Child.
Hug child.

当然,在代码中添加观察者还是不够灵活,最好的方式是把观察者配置在**.properties文件中,从配置文件中读取,从而添加观察者。

那么代码修改成为如下的方式。

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.*;
class WakeupEvent {
	
	private long time;
	private String location;
	private Child source;
	
	public WakeupEvent(long time,String location,Child source){
		
		this.time = time;
		this.location = location;
		this.source = source;
	}

	public long getTime() {
		return time;
	}

	public void setTime(long time) {
		this.time = time;
	}

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}

	public Child getSource() {
		return source;
	}

	public void setSource(Child source) {
		this.source = source;
	}
}
class Child{
	
	private List<Family> familyList=null;
	
	public Child(List<Family> list){
		
		this.familyList=list;
		System.out.println("Child sleep.");
		
		ExecutorService exeService = Executors.newSingleThreadExecutor();
		exeService.execute(new Runnable(){
			
			public void run() {
				
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				wakeup();
				
				//化主动监测为被动
				for(int i=0;i<familyList.size();i++)
				{
					familyList.get(i).wakeupAction(new WakeupEvent(System.currentTimeMillis(),"bed",Child.this));
				}
			}
		});
	}
	public void wakeup(){
		
		System.out.println("Child wake up.");
	}
}
interface Family{
	
	public void wakeupAction(WakeupEvent wakeup);
}
class Dad implements Family{
	
	public void wakeupAction(WakeupEvent wakeup){
		
		//根据WakeupEvent的不同情况作出不同的反应
		//代码略
		System.out.println("Feed Child.");
	}
}
class GrandFather implements Family{

	@Override
	public void wakeupAction(WakeupEvent wakeup) {
		
		System.out.println("Hug child.");
	}
}
public class Main{
	
	public static void main(String[] args){
		
		List<Family> list=new ArrayList<Family>();
	    //从配置文件中读取观察者
		Properties props = new Properties();
		try {
			props.load(Main.class.getClassLoader().getResourceAsStream("Observer.properties"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String[] obersvers = props.getProperty("Observers").split(",");
		for(String s:obersvers) {
			
			try {
				list.add((Family)Class.forName(s).newInstance());
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		
		Child child=new Child(list);
	}
}

配置文件Oberser.properties的内容为:

Observers=Dad,GrandFather

运行结果为:

Child sleep.
Child wake up.
Feed Child.
Hug child.

观察者模式还用在了java.awt.Button中,Button中有一系列的观察者ActionListener,在button被按下时调用这一系列ActionListener的actionPerformed方法。

代码如下:

import java.util.*;
class Button {
	
	private List<ActionListener> list = new ArrayList<ActionListener> ();
	
	public void addActionListener(ActionListener actionListener){
		
		list.add(actionListener);
	}
	public void pressButton() {
		
		for(int i=0;i<list.size();i++) {
			
			list.get(i).actionPerformed(new ActionEvent(this));
		}
	}
}
interface ActionListener {
	
	public void actionPerformed(ActionEvent e);
}
class MyActionListener implements ActionListener {

	@Override
	public void actionPerformed(ActionEvent e) {
		
		System.out.println(e.getSource()+"按钮被按了");
	}
}
class ActionEvent {
	
	private Button source;
	
	public ActionEvent(Button btn){
		
		this.source=btn;
	}
	public Object getSource() {
		
		return this.source;
	}
}
public class Test {
	
	public static void main(String[] args) {
		
		Button btn = new Button();
		btn.addActionListener(new MyActionListener());
		
		//当按钮被按下时
		btn.pressButton();
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值