您的位置:首页 > 其它

设计模式之观察者模式(Observer模式)

2011-04-01 22:58 162 查看
声明:本文参考了北京尚学堂马士兵老师的设计模式视频,表示感谢~~~

观察者设计模式:一个目标物件管理着若干个观察者物件,当目标物件发生改变时,

它会将这种改变通知给观察者们,然后观察者们作出相应的处理。

1.问题的提出

1) 小孩正在睡觉

2)醒来的的时候,爸爸需要喂东西给他吃

请编写代码模拟以上场景。

这个很好实现,请参考以下java代码:

/**
* 小孩类
*/
class Child implements Runnable{

private Dad d;

public Child(Dad d) {
this.d = d;
}

public void wakeUp() {
d.feed(this);
}

@Override
public void run() {
try {
Thread.sleep(5000);
wakeUp();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

/**
* 爸爸类
*/
class Dad {

public void feed(Child c) {
System.out.println("Dad feed !");
}
}

public class Test {

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


2.如果需要根据小孩醒来的时的状态,爸爸采取不同的措施,比如 早上醒来喂酸奶,中午喂饼干等,或者带他出去玩,请编码实现这种情况?

思路:我们可以定义一个小孩醒来时的事件,当小孩醒来的时候将事件告诉他爸爸。

/**
* 醒来时的事件类
*/
class WakeupEvent {

private long time;
private String loc;
private Child source;

public WakeupEvent(String loc, Child source, long time) {
super();
this.loc = loc;
this.source = source;
this.time = time;
}

public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public Child getSource() {
return source;
}
public void setSource(Child source) {
this.source = source;
}
}

/**
* 小孩类
*/
class Child implements Runnable{

private Dad d;

public Child(Dad d) {
this.d = d;
}

public void wakeUp() {
d.actionToWakeup(new WakeupEvent("bed", this, System.currentTimeMillis()));
}

@Override
public void run() {
try {
Thread.sleep(5000);
wakeUp();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

/**
* 爸爸类
*/
class Dad {

public void actionToWakeup(WakeupEvent e) {
System.out.println("Dad feed");
}
}

public class Test {

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


3.如果爷爷也需要对小孩醒来时的事件作出相应的处理,该怎么办呢?如果按照爸爸相同的实现方式,则child类改动比较大,有没有更好的实现方法?

思路:

1)因为都需要对小孩醒来时的事件作出相应的处理,我们可以抽象出一个接口,专门处理小孩醒来时的事件,凡是需要对小孩醒来时的事件作出处理的类都要实现该接口。

2)在child类中定义一个属性list,用来保存所有对小孩醒来时的事件作出响应的对象

/**
* 醒来时的事件
*/
class WakeupEvent {

private long time;
private String loc;
private Child source;

public WakeupEvent(String loc, Child source, long time) {
super();
this.loc = loc;
this.source = source;
this.time = time;
}

public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public Child getSource() {
return source;
}
public void setSource(Child source) {
this.source = source;
}
}

/**
* 醒来时的事件监听器
*/
interface WakeupListener {

void actionToWakeup(WakeupEvent e);
}

/**
* 小孩类
* @author zzp
*
*/
class Child implements Runnable{

private List<WakeupListener> wakeupListeners = new ArrayList<WakeupListener>();

public void addWakeupListener(WakeupListener l) {
wakeupListeners.add(l);
}

public void wakeUp() {
for(WakeupListener l : wakeupListeners) {
l.actionToWakeup(new WakeupEvent("bed", this, System.currentTimeMillis()));
}
}

@Override
public void run() {
try {
Thread.sleep(5000);
wakeUp();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

/**
* 爸爸类
* @author
*
*/
class Dad implements WakeupListener{

public void actionToWakeup(WakeupEvent e) {
System.out.println("Dad feed");
}
}

/**
* 爷爷类
* @author zzp
*
*/
class Grandfather implements WakeupListener {

@Override
public void actionToWakeup(WakeupEvent e) {
System.out.println("Grand father open TV");
}

}

public class Test {

public static void main(String[] args) {
Child c = new Child();
Dad d = new Dad();
c.addWakeupListener(d);
Grandfather gf = new Grandfather();
c.addWakeupListener(gf);
new Thread(c).start();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: