Java设计模式

Java实现23种设计模式(十六):观察者模式(重点掌握)

2020-06-11  本文已影响0人  依然慢节奏

二十三种设计模式分类

设计模式三大分类.jpg

一、概述

观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。

主要意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

优点

缺点

场景


二、实现

1. 结构图

观察者模式的主要角色如下。

观察者模式

PS:UML结构图可以参考,例子实现并不根据UML图来完成,灵活实现即可;

2. 实现

2.1 自己实现观察者模式

package cn.missbe.model.observer.primitive;

/**
 * Copyright (c) 2020.
 * Email: love1208tt@foxmail.com
 * @author lyg  2020/4/27 下午10:28
 * description:
 **/

public interface Observer {
    /**
     * 观察者接口,叫醒后发生的行为
     * @param event 叫醒事件
     */
    void actionWakeUp(WakeEvent event);
}
package cn.missbe.model.observer.primitive;

/**
 * Copyright (c) 2020.
 * Email: love1208tt@foxmail.com
 * @author lyg  2020/4/27 下午10:28
 * description: 简单封装的一个事件类
 **/

public class WakeEvent {
    /**叫醒发生时间点*/
    private long timestamp;
    /**叫醒时所处的位置*/
    private String location;
    /**源对象*/
    private  Object source;

    public WakeEvent(long timestamp, String location, Object source) {
        this.timestamp = timestamp;
        this.location = location;
        this.source = source;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    public String getLocation() {
        return location;
    }

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

    public Object getSource() {
        return source;
    }

    public void setSource(Object source) {
        this.source = source;
    }

    @Override
    public String toString() {
        return "WakeEvent{" + "timestamp=" + timestamp + ", location='" + location + '\'' + ", source=" + source + '}';
    }
}
package cn.missbe.model.observer.primitive;

/**
 * Copyright (c) 2020.
 * Email: love1208tt@foxmail.com
 * @author lyg  2020/4/27 下午10:33
 * description:观察都:Mum
 **/

public class Mum  implements Observer{
    /**Mum针对孩子醒了以后的处理方式*/
    private void hug(){
        System.out.println("Mus hug wu wu...");
    }

    @Override
    public void actionWakeUp(WakeEvent event) {
        hug();
    }
}
package cn.missbe.model.observer.primitive;

/**
 * Copyright (c) 2020.
 * Email: love1208tt@foxmail.com
 * @author lyg  2020/4/27 下午10:34
 * description:观察者:Dad
 **/

public class Dad implements Observer {
    /**Dad针对孩子醒了以后的处理方式*/
    private void feed(){
        System.out.println("Dad feed wu wu....");
    }

    @Override
    public void actionWakeUp(WakeEvent event) {
        feed();
    }
}
package cn.missbe.model.observer.primitive;

/**
 * Copyright (c) 2020.
 * Email: love1208tt@foxmail.com
 * @author lyg  2020/4/27 下午10:35
 * description:观察者:Dog
 **/

public class Dog implements Observer {
    /**狗针对孩子醒了以后的处理方式*/
    private void call(){
        System.out.println("Dog wang wang...");
    }
    @Override
    public void actionWakeUp(WakeEvent event) {
        call();
    }
}

package cn.missbe.model.observer.primitive;

import java.util.ArrayList;
import java.util.List;

/**
 * Copyright (c) 2020.
 * Email: love1208tt@foxmail.com
 *
 * @author lyg  2020/4/27 下午10:36
 * description: 简单具体目标,进行通知
 **/

public class ChildSubject {
    /**观察者集合*/
    List<Observer> observers = new ArrayList<>();
    /**孩子是否cry*/
    private boolean cry;

    public void attach(Observer observer) {
        observers.add(observer);
    }

    public void wakeUp() {
        cry = true;

        WakeEvent event = new WakeEvent(System.currentTimeMillis(), "bed", this);

        for (Observer observer : observers) {
            observer.actionWakeUp(event);
        }
        cry = false;
    }
}
package cn.missbe.model.observer.primitive;

/**
 * Copyright (c) 2020.
 * Email: love1208tt@foxmail.com
 * @author lyg  2020/4/27 下午10:39
 * description:
 * 观察者模式:同一事件发生,不同的观察都有不同的响应处理方式;
 **/

public class Main {
    public static void main(String[] args) {
        ChildSubject subject = new ChildSubject();
        /*添加观察者Mum*/
        subject.attach(new Mum());
        /*添加观察者Dad*/
        subject.attach(new Dad());
        /*添加观察者Dog*/
        subject.attach(new Dog());

        /*发生叫醒事件,通知所有观察者*/
        subject.wakeUp();
    }
}

2.1 利用JDK实现观察者模式

package cn.missbe.model.observer.javax;

import java.util.Observable;

/**
 * Copyright (c) 2020.
 * Email: love1208tt@foxmail.com
 * @author lyg  2020/4/27 下午10:26
 * description:被观察者(Observable)
 *   ///设置变化点,表示被观察者状态已经发生了变化
 *   setChanged();
 *   ///如果该对象发生了变化,由所示hasChanged方法,则通知其所有观察者,并调用clearChanged方法来指示该对象不再改变
 *   notifyObservers(args);
 **/

public class Earth extends Observable {
    private String weather = "晴朗";

    public String getWeather() {
        return weather;
    }

    public void setWeather(String weather) {
        this.weather = weather;
        ///设置变化点
        setChanged();
        ///通知观察者
        notifyObservers(weather);
    }

    @Override
    public String toString() {
        return "Earth{" +
                "weather='" + weather + '\'' +
                '}';
    }
}
package cn.missbe.model.observer.javax;

import java.util.Observable;
import java.util.Observer;

/**
 * Copyright (c) 2020.
 * Email: love1208tt@foxmail.com
 * @author lyg  2020/4/27 下午10:26
 * description: 观察者:Satellite
 * 当被观察者(Observable)状态发生变化时,观察者会捕捉到调用update方法
 **/

public class Satellite implements Observer {
    private String weather;
    /**
     * This method is called whenever the observed object is changed. An
     * application calls an <tt>Observable</tt> object's
     * <code>notifyObservers</code> method to have all the object's
     * observers notified of the change.
     *
     * @param o   the observable object.
     * @param arg an argument passed to the <code>notifyObservers</code>
     */
    @Override
    public void update(Observable o, Object arg) {
        weather = (String) arg;
        System.out.println("近期天气变化:" + weather);
        System.out.println("Observable:"+o);
    }
}
package cn.missbe.model.observer.javax;

/**
 * Copyright (c) 2020.
 * Email: love1208tt@foxmail.com
 * @author lyg  2020/4/27 下午10:26
 * description:
 **/

public class WeatherService {
    public static void main(String[] args) {
        Earth earth = new Earth();
        Satellite satellite = new Satellite();
        earth.addObserver(satellite);
        System.out.println("-----天气预报------");
        earth.setWeather("台风逼近....");
        earth.setWeather("暴雨....");
        earth.setWeather("火热....");
        earth.setWeather("大风....");
    }
}
上一篇 下一篇

猜你喜欢

热点阅读