JAVA设计模式-----观察者模式

菜鸟自学的设计模式---即用最简单的方法描述,简单易懂。

总结了书中的内容

观察者是让被观察者的属性发生改变时,相对的观察者会收到通知所有相关属性成员都会发生改变,观察者模式增强了复用率和扩展度。

被观察者

用了jdk自带的被观察者类(Observable),把自己写的被观察者继承Observable即可成为被观察者,先贴出源码

package java.util;

public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;

    public Observable() {
        obs = new Vector<>();
    }

    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }


    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }

    public void notifyObservers() {
        notifyObservers(null);
    }

    public void notifyObservers(Object arg) {

        Object[] arrLocal;

        synchronized (this) {
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

    protected synchronized void setChanged() {
        changed = true;
    }

    protected synchronized void clearChanged() {
        changed = false;
    }

    
    public synchronized boolean hasChanged() {
        return changed;
    }

    public synchronized int countObservers() {
        return obs.size();
    }
}

可以在notifyObservers方法中看出changed属性成员是一个用来标记是否发送通知的通道,Vector<Observer> obs 是一个用来存放观察者的集合

public void notifyObservers(Object arg) {
       //用来接收观察者的数组(用数组可能更方便设计把)
        Object[] arrLocal;

        synchronized (this) {
            //如果通道未打开则不将集合中的观察者放入数组
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }
        //通过循环调用update接口来向观察者发送通知
        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

在父类Observable中各种方法

构造方法用来实例化Vector集合

 public Observable() {
        obs = new Vector<>();
}

绑定观察者的方法

public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
}

删除观察者的方法

public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
}

通知观察者的方法

public void notifyObservers() {
        notifyObservers(null);
}

public void notifyObservers(Object arg) {
        
        Object[] arrLocal;

        synchronized (this) {
            
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

清除所有观察者的方法

 public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

打开通知通道的方法和关闭通知通道的方法

protected synchronized void setChanged() {
        changed = true;
    }

protected synchronized void clearChanged() {
        changed = false;
    }

新建一个被观察者的类继承jdk自带的被观察者类Observable(java.util.Observable)同时加入成员变量a和b,编写调用父类通知观察者(notifyObservers)的方法mechanged(),和一个修改值的方法同时调用mechanged(),这样在修改类的属性时将会通知所有的观察者修改对应值

package com.domain;

import java.util.Observable;

/**
 * 这是一个被观察者的类,能够在值修改时通知观察者
 */
public class ZT extends Observable {
    private int a;
    private int b;

    public void setA(int a) {
        this.a = a;
    }

    public void setB(int b) {
        this.b = b;
    }

    public void mechanged(){
        /**打开通道*/
        setChanged();
        /**发送通知*/
        notifyObservers();
    }
    /**
     * 通过调用此方法改变值,同时发送通知
     */
    public void setmechanged(int a, int b){
        this.a=a;
        this.b=b;
        //update();
        mechanged();
    }

    public int getA() {
        return a;
    }

    public int getB() {
        return b;
    }
}

观察者

jdk同时也为用户提供了观察者的接口Observer,接口中有一个update方法。在被观察者Observable中可以看到通知观察者的方法中有一个循环调用该接口方法的代码



        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);

即调用实现该方法就会被被通知者调用

所以在观察中类中实现该接口

package com.domain;

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

/**
 * 这是一个观察者的类,能够在被观察者属性值发生改变时,获得被观察者的通知
 */
public class GCZA implements Observer {
    public int a;
    public int b;
    public Observable Observable;


    public GCZA(Observable Observable){
        /**通过构造器绑定被观察者*/
        this.Observable=Observable;
        Observable.addObserver(this);
    }

    @Override
    public void update(Observable o , Object arg) {
        /**从被观察者处获取字段属性*/
        ZT zt=(ZT)o;
        this.a=zt.getA();
        this.b=zt.getB();
        dis();
    }

    /**打印该通知属性的方法*/
    public void dis(){
        System.out.println("a"+":"+a);
        System.out.println("b"+":"+b);
        System.out.println("a+b="+(a+b));
    }
}

在Observable的通知方法中((Observer)arrLocal[i]).update(this, arg);传入了this所以调用该参数o既可以获取被通知者的对象,然后可以通过对象获取成员属性同时这样就接收到了通知,如果需要多个观察者那么同时实现接口即可

测试

package com.test;

import com.domain.GCZA;
import com.domain.ZT;

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

public  class Test extends Observable {
    public static void main(String[] args) {
        //创建被观察者对象
        ZT observable=new ZT();
        //创建观察者对象同时绑定被观察者
        new GCZA(observable);
        //修改属性同时发送通知
        observable.setmechanged(1,2);
    }
}

结果

a:1
b:2
a+b=3

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GeoPandas是一个开源的Python库,旨在简化地理空间数据的处理和分析。它结合了Pandas和Shapely的能力,为Python用户提供了一个强大而灵活的工具来处理地理空间数据。以下是关于GeoPandas的详细介绍: 一、GeoPandas的基本概念 1. 定义 GeoPandas是建立在Pandas和Shapely之上的一个Python库,用于处理和分析地理空间数据。 它扩展了Pandas的DataFrame和Series数据结构,允许在其中存储和操作地理空间几何图形。 2. 核心数据结构 GeoDataFrame:GeoPandas的核心数据结构,是Pandas DataFrame的扩展。它包含一个或多个列,其中至少一列是几何列(geometry column),用于存储地理空间几何图形(如点、线、多边形等)。 GeoSeries:GeoPandas中的另一个重要数据结构,类似于Pandas的Series,但用于存储几何图形序列。 二、GeoPandas的功能特性 1. 读取和写入多种地理空间数据格式 GeoPandas支持读取和写入多种常见的地理空间数据格式,包括Shapefile、GeoJSON、PostGIS、KML等。这使得用户可以轻松地从各种数据源中加载地理空间数据,并将处理后的数据保存为所需的格式。 2. 地理空间几何图形的创建、编辑和分析 GeoPandas允许用户创建、编辑和分析地理空间几何图形,包括点、线、多边形等。它提供了丰富的空间操作函数,如缓冲区分析、交集、并集、差集等,使得用户可以方便地进行地理空间数据分析。 3. 数据可视化 GeoPandas内置了数据可视化功能,可以绘制地理空间数据的地图。用户可以使用matplotlib等库来进一步定制地图的样式和布局。 4. 空间连接和空间索引 GeoPandas支持空间连接操作,可以将两个GeoDataFrame按照空间关系(如相交、包含等)进行连接。此外,它还支持空间索引,可以提高地理空间数据查询的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值