观察者模式的初始学习--自己实现

观察者模式:首先要理解观察者模式的定义,对象间一对多的关系,当其中的一个Object变化[subject]时,其他的依赖这个对象的对象[Observer],都会受到相应的通知,并且自动更新自己状态.

其中目标对象,是源头:subject,它应该包含有 add()  \  remove()  \  notify()  基本的单个方法,分别用于 注册观察者, 删除观察者,以及通知观察者.

而观察者对象: Observer 则应该有 update()方法,在收到依赖对象的变化通知时候,就自动执行update的方法,更新自己的状态信息.

代码实现观察者模式 --->基本的步骤如下:

1,(subject)目标对象(接口)的建立,其中规定统一的方法规则.

2,具体目标类的建立,都必须要实现subject的接口.

3,观察者接口的定义,Observer的接口,包含有update方法.

4,具体的观察者的建立,实现观察者接口.

具体的代码如下:

subject的接口的建立:

public interface Subject {

    /**
     *
     * 功能描述: <br>
     * 〈功能详细描述〉注册成为观察者
     *
     * @param observer
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    void registerObserver(Observer observer);

    /**
     *
     * 功能描述: <br>
     * 〈功能详细描述〉取消成为观察者
     *
     * @param observer
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    void removeObserver(Observer observer);
    /**
     *
     * 功能描述: <br>
     * 〈功能详细描述〉通知所有的观察者
     *
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    void notifyObservers();

}

具体的目标类的建立: 里面是包含了自己写的方便测试的代码.

public class GoodsData implements Subject {

    private ArrayList<Observer> observers;

    private String name;

    private int num;

    private int price;

    public GoodsData() {
        observers = new ArrayList<Observer>();
    }

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

    @Override
    public void removeObserver(Observer observer) {
        int i = observers.indexOf(observer);
        if (i >= 0) {
            observers.remove(i);
        }

    }

    @Override
    public void notifyObservers() {
        for (Observer o : observers) {
            o.update(name, num, price);
        }
    }

    /**
     *
     * 功能描述: <br>
     * 〈功能详细描述〉商品参数变化时 通知给个观察者变化
     *
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void goodsChanged() {
        notifyObservers();
    }

    /**
     *
     * 功能描述: <br>
     * 〈功能详细描述〉实时获取商品的参数信息,测试方法
     *
     * @param name
     * @param num
     * @param price
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void setGoodsData(String name, int num, int price) {
        this.name = name;
        this.num = num;
        this.price = price;
        goodsChanged();
    }
}

观察者的接口的定义: 主要定义统一的update方法

public interface Observer {

    /**
     *
     * 功能描述: <br>
     * 〈功能详细描述〉观察者跟新主题最新的数据
     *
     * @param name 名称
     * @param num  数量
     * @param price 价格
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    void update(String name, int num, int price);

}

定义具体的观察者的类定义: 当然,里面也包含了一些方便测试的附加操作代码.

public class SuguoMarket implements Observer, DisplayElement {

    private String name;

    private int num;

    private int price;

    private Subject goodsMarket;

    public SuguoMarket(Subject goodsMarket) {
        this.goodsMarket = goodsMarket;
        goodsMarket.registerObserver(this);
    }

    /**
     *
     * 功能描述: <br>
     * 〈功能详细描述〉取消注
     *
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void removeObserver() {
        goodsMarket.removeObserver(this);
    }

    @Override
    public void display() {
        System.out.println("名称:" + name + "数量:" + num + "价格:" + price);
    }

    @Override
    public void update(String name, int num, int price) {
        this.name = "苏果" + name;
        this.num = num;
        this.price = price;
        display();
    }

}

最后简单的写个测试类的代码,方便运行查询实时效果:

public class MarkertTest {

    public static void main(String[] args) {

        GoodsData goods = new GoodsData();
        SuguoMarket suguo = new SuguoMarket(goods);
        goods.setGoodsData("香烟", 20, 100);
        goods.setGoodsData("啤酒", 100, 5);
        goods.setGoodsData("可樂", 100, 2);

        // 取消注册
        suguo.removeObserver();
        goods.setGoodsData("口香糖", 100, 2);
    }

}

到此为止,一个简单的观察者模式就建立完成了,后面会继续采用java的jdk自有的api来实现观察者模式

时间: 2024-08-03 08:11:59

观察者模式的初始学习--自己实现的相关文章

JDBC+MYSQL初始学习

JDBC+MYSQL初始学习 一.学习准备 Eclipse 开发工具  + mysql数据库+navicat 数据库连接工具 Mysql的数据库连接驱动jar包  + testing测试集成+maven工具集成 Jar的获取方法: 1.直接下载需要的jar,导入项目中使用. 2.在maven工程中加入依赖:本文使用的maven依赖: <dependency> <groupId>mysql</groupId> <artifactId>mysql-connect

Python初始学习必要掌握知识点(5分钟速学)

1.字符串 python中单引号和双引号使用完全相同. 使用三引号('''或""")可以指定一个多行字符串. 转义符 '\' 反斜杠可以用来转义,使用r可以让反斜杠不发生转义.. 如 r"this is a line with \n" 则\n会显示,并不是换行. 按字面意义级联字符串,如"this " "is " "string"会被自动转换为this is string. 字符串可以用 + 运算

bootstrap 初始学习篇

<!DOCTYPE html> <html> <head> <meta charset="{CHARSET}"> <title></title> <link rel="stylesheet" href="css/bootstrap.min.css">//链接到样式表 原始位置 </head> <body> <button class=

C# 初始学习心情

当听说需要转做.net的时候.内心是忐忑不安的.因为突然从前端转向后端,几乎完全颠倒了...一个注重界面实现功能.一个注重逻辑的开发,然并卵,服从需求吧. 虽说公司需要你转.但是时间是不允许的,所以只能边学边做了,还在现在有强大的网络,让一切不可能变成了可能,代码无非就是复制粘贴嘛,但是你要懂它.了解它.公司只给了2天时间熟悉语法,然后就开始了,两天时间只看了个大概的语法和基础的SQL Sever语句.只能随后在用到时候利用度娘了.加油加油加油吧.....

LInux初始学习篇:基本命令使用

1.type.file命令的区别:(1)type :用于查看一条命令是内置命令还是外部命令使用格式:type command若是内部命令,显示 builtin若是外部命令,显示为命令文件路径:例子:[[email protected]_0_2_centos /]# type cdcd is a shell builtin [[email protected]_0_2_centos /]# type whowho is /usr/bin/who (2)file:用于查看一个文件的类型,文本文件,还

Flume-ng+Kafka+storm的学习笔记

Flume-ng Flume是一个分布式.可靠.和高可用的海量日志采集.聚合和传输的系统. Flume的文档可以看http://flume.apache.org/FlumeUserGuide.html 官方的英文文档 介绍的比较全面. 不过这里写写自己的见解 这个是flume的架构图 从上图可以看到几个名词: Agent: 一个Agent包含Source.Channel.Sink和其他的组件.Flume就是一个或多个Agent构成的. Source:数据源.简单的说就是agent获取数据的入口

一、WCF学习之旅-创建第一个服务

WCF基本介绍:http://baike.baidu.com/link?url=TGjLYt3HS4dt4-hIiGRknLy6udRsZ52QxJz9cmRKlR4NXbP9rCZDsKn2fDfGeBEfyQL9XlTMy_aW4Zno3HEkKa WCF有三种通信模式:单向.请求-响应.双工.这些通信模式留待后面再继续学习和讲解. 今天要学习的是创建一个测试的demo,所谓的hello world入门级程序.OK,let's start! 1.创建解决方案和项目 打开vs2015,文件>新

Selenium2学习-004-WebUI自动化实战实例-002-百度登录

此文主要通过 百度登录 功能,进行 Selenium2 的实战实例讲解.文中所附源代码于 2015-01-17 23:33 亲测通过,敬请亲们阅览.同时,您也可参考此文进行其他网站(例如 京东.易迅.天猫等)的登录(一般登录流程基本相同,若需填写验证码,因目前验证码识别不方便,初始学习时可让脚本运行到添加验证码时人工输入.在单位进行此部分的自动化脚本编写时,最好取得开发的支持使用万能验证码,方便脚本编写),进行编写登录自动化测试脚本,若您直接使用此文所附的源代码运行测试,则需要将文中 账户名和密

学习笔记TF040:多GPU并行

TensorFlow并行,模型并行,数据并行.模型并行根据不同模型设计不同并行方式,模型不同计算节点放在不同硬伯上资源运算.数据并行,比较通用简便实现大规模并行方式,同时使用多个硬件资源计算不同batch数据梯度,汇总梯度全局参数更新. 数据并行,多块GPU同时训练多个batch数据,运行在每块GPU模型基于同一神经网络,网络结构一样,共享模型参数. 同步数据并行,所有GPU计算完batch数据梯度,统计将多个梯度合在一起,更新共享模型参数,类似使用较大batch.GPU型号.速度一致时,效率最