栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式——观察者模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式——观察者模式

前言

        本文简单介绍了关于设计模式的一种,观察者模式

        (上一篇) 设计模式——装饰者模式_秋雨绵绵-CSDN博客


目录

一、观察者模式的定义和特点

二、观察者模式的结构

三、代码实例


一、观察者模式的定义和特点

        观察者模式的定义:

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

        特点:

  1. 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则。

  2. 目标与观察者之间建立了一套触发机制。

二、观察者模式的结构

        实现观察者模式时要注意具体目标对象和具体观察者对象之间不能直接调用,否则将使两者之间紧密耦合起来,这违反了面向对象的设计原则。 观察者模式的主要角色如下。

        

        Subject类:他把所有对观察者对象的引用保存在一个聚合里,每个主题都可以有任何数量的观察者,抽象主题提供一个接口,可以增加和删除任意的观察者对象

        observer类:抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己

        ConcreteSubject:具体主题,将有关状态存入具体观察者对象,在具体主题的内部状态改变时,给所有登记过的的观察者发出通知

        ConcreteObserver:具体观察者,实现抽象观察者角色所要求的的更新接口,以便使本身的状态与主题的状态向协调

三、代码实例

        现在有一个需求,各网站需要订阅天气需求, 我们这边要及时更新并发送天气信息,且我们可以自由的注册或者移除想要发送的网站,用观察者模式实现。

        如果我们用传统的模式实现该案例,那么会出现一个问题,就是如果我们要修改网站,那可能回去改动网站类的代码,和我们操作更新数据的代码,这不符合我们的开闭原则,因此我们采用观察者模式去实现,因为他也是一种一对多的依赖关系,生活中这种案例多不胜数,例如订阅杂志,等。

        结构图如下

        代码示例

        抽象目标类Subject

        

package com.observerPattern.weatherCase;


public interface Subject {
    
    void registerObserver(Observer o);
    
    void removeObserver(Observer o);
    
    void notifyObservers();
}

        具体目标WeatherDate类

package com.observerPattern.weatherCase;

import java.util.ArrayList;


public class WeatherDate implements Subject{
    private float temperature;
    private float pressure;
    private float humidity;
    private ArrayList observers;


    
    public WeatherDate() {
        this.observers = new ArrayList();
    }

    public float getTemperature() {
        return temperature;
    }

    public float getPressure() {
        return pressure;
    }

    public float getHumidity() {
        return humidity;
    }

    
    public void dateChange() {
        notifyObservers();
    }

    
    public void setDate(float temperature,float pressure,float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        dateChange();
    }


    
    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    
    @Override
    public void removeObserver(Observer o) {
        if(observers.contains(o)) {
            observers.remove(o);
        }

    }

    
    @Override
    public void notifyObservers() {
        for(int i = 0;i< observers.size();i++) {
            observers.get(i).update(this.temperature,this.pressure,this.humidity);
        }
    }
}

        抽象观察者Observer:

package com.observerPattern.weatherCase;


public interface Observer {
    
    void update(float temperature,float pressure,float humidity);
}

        具体观察者1

        

package com.observerPattern.weatherCase;


public class CurrentCondition implements Observer{

    private float temperature;
    private float pressure;
    private float humidity;

    
    @Override
    public void update(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        display();
    }
    
    public void display() {
        System.out.println("测试显示当前气温:" + temperature + "度");
        System.out.println("测试显示当前压力:" + pressure + "帕");
        System.out.println("测试显示当前湿度:" + humidity + "Rh");
    }
}

        具体观察者2:
        

package com.observerPattern.weatherCase;


public class SinaNet implements Observer{
    private float temperature;
    private float pressure;
    private float humidity;

    
    @Override
    public void update(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        display();
    }
    
    public void display() {
        System.out.println("=======新浪网站=======");
        System.out.println("新浪显示当前气温:" + temperature + "度");
        System.out.println("新浪显示当前压力:" + pressure + "帕");
        System.out.println("新浪显示当前湿度:" + humidity + "Rh");
    }
}

        客户端测试类

        

package com.observerPattern.weatherCase;


public class ClientTest {
    public static void main(String[] args) {

        //创建一个weatherDate具体目标
        WeatherDate weatherDate = new WeatherDate();

        //创建一个观察者
        CurrentCondition currentCondition = new CurrentCondition();

        //注册一个观察者
        weatherDate.registerObserver(currentCondition);

        //注册新浪
        SinaNet sinaNet = new SinaNet();
        weatherDate.registerObserver(sinaNet);

        //测试更新
        System.out.println("通知给各观察者");
        weatherDate.setDate(3,65,12);

        //测试移除
        weatherDate.removeObserver(currentCondition);

        System.out.println("========================");
        System.out.println("第二次更新");
        weatherDate.setDate(6,88,16);
    }
}

        这种好处是我们如果有新的网站的加入,那么直接添加一个观察者类即可,不用修改代码

以及删除,注册都是独立开来的。 

                                                                                                        参考:大话设计模式

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/680382.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号