居然还能通过给孩子喂奶这件事了解Observer观察者模式

 Observer观察者模式是Java23种设计模式中的一种,也是一个事件处理模型。

这里通过一个生活中的小事来了解Observer观察者模式。这个设计模式十分的重要,企业中的事件处理通常是观察者与责任链结合来完成设计。
先了解需求:
有一个小婴儿,正在床上睡着,突然他醒了并且大哭起来,他的爸爸赶紧给他喂奶。模拟这个事件的过程。
这次,我们通过逐步进行完善的方式写了7个版本的代码,循序渐进的讲解了Observer观察者模式中观察者与被观察者的各种关系及操作。

最后感谢大家的关注
欢迎添加qq 1723082823 进入我们的粉丝群 获取更多更新视频资料!

第一个版本
/**
 * 披着面向对象外衣的面向过程
 */
public class Main {
    public static void main(String[] args) {
        boolean cry = false;
        while(!cry) {
            //进行处理
        }
    }
}
第二个版本
class Child {										//婴儿
    private boolean cry = false;
    public boolean isCry() {					//哭的方法
        return cry;
    }
    public void wakeUp() {				//醒的方法
        System.out.println("Waked Up! Crying wuwuwuwu...");
        cry = true;
    }
}
public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        while(!child.isCry()) {						//循环判断是否在哭
            try {
                Thread.sleep(1000);					//等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("observing...");
        }
    }
}

在这个版本中,已经可以看到面向对象进行编程的实际情况了。将可以抽象出来的类设置出来代表婴儿,并且为这个类添加方法。在主方法中设置一个循环,一直等待婴儿哭的事件发生,效率低下。

第三个版本
class Child {
    private boolean cry = false;
    private Dad d = new Dad();				//私有一个婴儿爸爸的对象
    public boolean isCry() {
        return cry;
    }
    public void wakeUp() {
        cry = true;
        d.feed();									//婴儿哭的时候,直接调用爸爸对象的喂奶方法
    }
}
class Dad {								//婴儿的爸爸
    public void feed() {				//给婴儿喂奶的动作
        System.out.println("dad feeding...");
    }
}
public class Main {
    public static void main(String[] args) {
        Child c = new Child();
        //do sth
        c.wakeUp();									//不需要循环判断是否哭了
    }
}

最后感谢大家的关注
欢迎添加qq 1723082823 进入我们的粉丝群 获取更多更新视频资料!

这个版本的实例就是将婴儿爸爸喂奶的动作加入到婴儿的醒事件中,这时,只要婴儿睡醒就会自动调用他爸爸的喂奶的方法,不用for循环一直等待浪费时间了。
==>>这个版本中加入了 观察者,并且将观察者的方法加入到被观察者中,当被观察者的事件发生时,就会直接调动观察者的动作,省去了一直等待的时间浪费。

第四个版本

现实生活中,一个婴儿哭了之后,可能会有很多的情况发生,比如:他妈妈抱着哄他,他爸爸给他喂奶,他奶奶听见孩子哭到他爸妈屋问孩子怎么哭了?等等。
所以这个版本中我们添加了多个观察者。

class Child {
    private boolean cry = false;
    private Dad dad = new Dad();
    private Mum mum = new Mum();
    private Dog dog = new Dog();
    public boolean isCry() {
        return cry;
    }
    public void wakeUp() {
        cry = true;
        dad.feed();
        dog.wang();
        mum.hug();
    }
}
/**
*加入多个观察者
*/
class Dad {
    public void feed() {
        System.out.println("dad feeding...");
    }
}
class Mum {
    public void hug() {
        System.out.println("mum hugging...");
    }
}
class Dog {
    public void wang() {
        System.out.println("dog wang...");
    }
}
public class Main {
    public static void main(String[] args) {
        Child c = new Child();
        //do sth
        c.wakeUp();
    }
}

最后感谢大家的关注
欢迎添加qq 1723082823 进入我们的粉丝群 获取更多更新视频资料!

虽然现在的编程更接近现实,但是还是有缺点:如果要添加一个新的观察者会很麻烦,而且观察者的事件与婴儿的事件耦合太紧密。

第五个版本

在这个版本中,解决上个版本中存在的耦合度太高的问题。

class Child {
    private boolean cry = false;
    private List<Observer> observers = new ArrayList<>();			//新建一个列表用来存储观察者
    {
        observers.add(new Dad());
        observers.add(new Mum());
        observers.add(new Dog());
    }
    public boolean isCry() {
        return cry;
    }
    public void wakeUp() {
        cry = true;
        for(Observer o : observers) {
            o.actionOnWakeUp();
        }
    }
}
interface Observer {								//设计一个接口
    void actionOnWakeUp();						//存储当婴儿醒了之后所做的动作
}
class Dad implements Observer {          //所有观察者实现Observer接口
    public void feed() {
        System.out.println("dad feeding...");
    }
    @Override											//重写接口中的方法
    public void actionOnWakeUp() {
        feed();
    }
}
class Mum implements Observer {
    public void hug() {
        System.out.println("mum hugging...");
    }
    @Override
    public void actionOnWakeUp() {
        hug();
    }
}
class Dog implements Observer {
    public void wang() {
        System.out.println("dog wang...");
    }
    @Override
    public void actionOnWakeUp() {
        wang();
    }
}
public class Main {
    public static void main(String[] args) {
        Child c = new Child();
        //do sth
        c.wakeUp();
    }
}

到此为止我们做的已经很多了,现在我们考虑一下,如何根据被观察发生的具体事件,让不同的观察者去进行处理。

第六个版本
class Child {
    private boolean cry = false;
    private List<Observer> observers = new ArrayList<>();
    {
        observers.add(new Dad());
        observers.add(new Mum());
        observers.add(new Dog());
    }
    public boolean isCry() {
        return cry;
    }
    public void wakeUp() {
        cry = true;
        wakeUpEvent event = new wakeUpEvent(System.currentTimeMillis(), "bed");
        for(Observer o : observers) {
            o.actionOnWakeUp(event);
        }
    }
}
//事件类 表示婴儿睡醒这个事件
class wakeUpEvent{
    long timestamp;
    String loc;
    public wakeUpEvent(long timestamp, String loc) {
        this.timestamp = timestamp;
        this.loc = loc;
    }
}
interface Observer {
    void actionOnWakeUp(wakeUpEvent event);
}
class Dad implements Observer {
    public void feed() {
        System.out.println("dad feeding...");
    }
    @Override
    public void actionOnWakeUp(wakeUpEvent event) {
        feed();
    }
}
class Mum implements Observer {
    public void hug() {
        System.out.println("mum hugging...");
    }
    @Override
    public void actionOnWakeUp(wakeUpEvent event) {
        hug();
    }
}
class Dog implements Observer {
    public void wang() {
        System.out.println("dog wang...");
    }
    @Override
    public void actionOnWakeUp(wakeUpEvent event) {
        wang();
    }
}
public class Main {
    public static void main(String[] args) {
        Child c = new Child();
        //do sth
        c.wakeUp();
    }
}
  • 在Observer观察者模式中
    Event是必须要有的,Source是事件源对象、被观察者,Listener是事件观察者,Event是事件本身。
    事件源对象拥有很多的观察者,会发出具体的Event,Observer观察到Event的时候,作出具体的反应actionOnEvent。
第七个版本
class Child {
    private boolean cry = false;
    private List<Observer> observers = new ArrayList<>();
    {
        observers.add(new Dad());
        observers.add(new Mum());
        observers.add(new Dog());
    }
    public boolean isCry() {
        return cry;
    }
    public void wakeUp() {
        cry = true;
        wakeUpEvent event = new wakeUpEvent(System.currentTimeMillis(), "bed", this);
        for(Observer o : observers) {
            o.actionOnWakeUp(event);
        }
    }
}
class wakeUpEvent{
    long timestamp;
    String loc;
    Child source;
    public wakeUpEvent(long timestamp, String loc, Child source) {
        this.timestamp = timestamp;
        this.loc = loc;
        this.source = source;
    }
}
interface Observer {
    void actionOnWakeUp(wakeUpEvent event);
}
class Dad implements Observer {
    public void feed() {
        System.out.println("dad feeding...");
    }
    @Override
    public void actionOnWakeUp(wakeUpEvent event) {
        feed();
    }
}
class Mum implements Observer {
    public void hug() {
        System.out.println("mum hugging...");
    }
    @Override
    public void actionOnWakeUp(wakeUpEvent event) {
        hug();
    }
}
class Dog implements Observer {
    public void wang() {
        System.out.println("dog wang...");
    }
    @Override
    public void actionOnWakeUp(wakeUpEvent event) {
        wang();
    }
}
public class Main {
    public static void main(String[] args) {
        Child c = new Child();
        //do sth
        c.wakeUp();
    }
}

在事件(wakeUpEvent)中封装了Child source(源对象)
当需要source时就可以直接把source get出来,不需要时就不用
最后感谢大家的关注
欢迎添加qq 1723082823 进入我们的粉丝群 获取更多更新视频资料!

猜你喜欢

转载自blog.csdn.net/yxxylucy/article/details/95082385