观察者模式 java 举例_java设计模式--观察者模式

观察者模式

观察者--OOD线程

简单理解

起一个被观察者线程和一个观察者线程。观察者不断的循环检查被观察者状态是否发生改变。此设计缺点,因为需要不断的循环进行监视,所以耗CPU资源。

举例场景

孩子在睡觉,醒后要吃东西,父亲不断的监视者看孩子有没有醒

代码实现

child

package observersOOD;

/**

* 观察者模式-OOD线程

* 起一个被观察者线程和一个观察者线程。观察者不断的循环检查被观察者状态是否发生改变

* 案例:孩子在睡觉,醒后要吃东西,父亲不断的监视者看孩子有没有醒

*/

public class Child implements Runnable{

private boolean wakenUp = false;

public boolean isWakenUp() {

return wakenUp;

}

public void setWakenUp(boolean wakenUp) {

this.wakenUp = wakenUp;

}

public void wakeUp(){

System.out.println("孩子醒了....");

wakenUp = true;

}

public void run() {

try {

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

}

wakeUp();

}

}

Dad类

package observersOOD;

public class Dad implements Runnable {

private Child child;

public Dad(Child child) {

this.child = child;

}

public void feed(Child child){

System.out.println("feed child......");

}

public void run() {

while (!child.isWakenUp()){

try {

System.out.println("我在监视孩子。。。。");

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

feed(this.child);

}

public static void main(String[] args) {

Child child = new Child();

Dad dad = new Dad(child);

Thread childThread = new Thread(child);

Thread dadThread = new Thread(dad);

childThread.start();

dadThread.start();

}

}

test

public static void main(String[] args) {

Child child = new Child();

Dad dad = new Dad(child);

Thread childThread = new Thread(child);

Thread dadThread = new Thread(dad);

childThread.start();

dadThread.start();

}

运行结果

我在监视孩子。。。。

我在监视孩子。。。。

我在监视孩子。。。。

我在监视孩子。。。。

孩子醒了....

feed child......

改进(上面由于父类需要主动监视孩子,需要通过不断的循环实现,太浪费资源)。

改进后有孩子醒后主动通知父亲。

class Child implements Runnable {

private Dad dad;

public Child(Dad dad) {

this.dad = dad;

}

public void wakeUp(){

dad.feed(this);

}

@Override

public void run() {

try {

Thread.sleep(3000);

} catch (Exception e) {

e.printStackTrace();

}

wakeUp();

}

}

class Dad {

void feed(Child c) {

System.out.println("feed child");

}

}

public class Test {

public static void main(String[] args) {

Dad d = new Dad();

Child c = new Child(d);

new Thread(c).start();

}

}

把孩子睡醒后封装成事件

class WakenUpEvent{

private long time;

private String location;

private Child source;

public WakenUpEvent(long time, String location, Child source) {

super();

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 implements Runnable {

private Dad dad;

public Child(Dad dad) {

this.dad = dad;

}

public void wakeUp(){

dad.actionToWakenUp(new WakenUpEvent(System.currentTimeMillis(), "bed", this));

}

@Override

public void run() {

try {

Thread.sleep(3000);

} catch (Exception e) {

e.printStackTrace();

}

wakeUp();

}

}

class Dad {

public void actionToWakenUp(WakenUpEvent e) {

System.out.println(e.getTime());

System.out.println(e.getLocation());

System.out.println(e.getSource());

System.out.println("Fedd the child");

}

}

public class Test {

public static void main(String[] args) {

Dad d = new Dad();

Child c = new Child(d);

new Thread(c).start();

}

}

上面例子中child都会持有dad类,如果观察者发生改变,需要修改代码很不方便。

解决方法:动态的注册到被观察者中。持有addListener方法

定义监听者接口

interface WakenUpListener {

public void actionToWakenUp(WakenUpEvent e);

}

定义实际监听者

class Dad implements WakenUpListener {

public void actionToWakenUp(WakenUpEvent e) {

System.out.println("Fedd the child");

}

}

class GrandFather implements WakenUpListener {

public void actionToWakenUp(WakenUpEvent e) {

System.out.println("抱孩子");

}

}

定义child,child中持有添加观察者方法,当醒后一一通知他的观察者

package observersOOD.Listener;

import java.util.ArrayList;

import java.util.List;

public class Child implements Runnable{

public Child() {

}

private List wakenUpListeners = new ArrayList();

//提供一个注册观察者方法

public void addWakenUpListener(WakenUpListener wakenUpListener){

wakenUpListeners.add(wakenUpListener);

}

//提供一个通知方法

public void wakeUp(){

for (int i=0;i

WakenUpEvent wakenUpEvent = new WakenUpEvent(111111L,"111111",this);

wakenUpListeners.get(i).actionToWakenUp(new WakenUpEvent(1111L,"1111",this));

}

}

public void run() {

try {

Thread.sleep(3000L);

} catch (InterruptedException e) {

e.printStackTrace();

}

wakeUp();

}

}

定义Test类

package observersOOD.Listener;

public class Test {

public static void main(String[] args) {

WakenUpListener dad = new Dad();

WakenUpListener grandFather = new GrandFather();

Child child = new Child();

child.addWakenUpListener(dad);

child.addWakenUpListener(grandFather);

Thread thread = new Thread(child);

thread.start();

}

}

运行结果

1111

1111

开始喂孩子....

抱孩子......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值