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

定义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
开始喂孩子....
抱孩子......

你可能感兴趣的:(java设计模式--观察者模式)