java常用设计模式四:观察者模式
1、定义
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。观察者模式又叫发布-订阅(Publish/Subscribe)模式。
2、观察者模式的四种基本角色
- 抽象被观察者角色:也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
- 抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
- 具体被观察者角色:也就是一个具体的主题,在集体主题的内部状态改变时,向所有登记过的观察者发出通知。
- 具体观察者角色:实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的状态相协调。
3、示例程序
(以一个游戏玩家和游戏管理员为例,游戏管理员为被观察者,游戏玩家为观察者,当游戏维护了,游戏管理员会通知每一位玩家“游戏维护中,2小时后恢复”,游戏恢复后再通知每一位玩家“游戏恢复正常,可以游戏了”)
1)抽象被观察者
public interface IGameAdmin {
    void addGamePlayer(IGamePlayer iGamePlayer);
    void removeGamePlayer(IGamePlayer iGamePlayer);
    void notifyAllGamePlayer();
    void setGameMessage(String message);
}
2)抽象观察者
public interface IGamePlayer {
    void updateMessage(String message);
}
3)具体被观察者
public class GameAdmin implements IGameAdmin {
    //注意集合里面存的是抽象观察者,这样是为了以后观察者和被观察者解耦,每一方的具体角色的改变不影响另一方
    private List<IGamePlayer> gamePlayers;
    private String message;
    public GameAdmin(){
        gamePlayers = new ArrayList<IGamePlayer>();
    }
    public void addGamePlayer(IGamePlayer iGamePlayer) {
        gamePlayers.add(iGamePlayer);
    }
    public void removeGamePlayer(IGamePlayer iGamePlayer) {
        gamePlayers.remove(iGamePlayer);
    }
    public void notifyAllGamePlayer() {
        for(IGamePlayer iGamePlayer:gamePlayers){
            iGamePlayer.updateMessage(message);
        }
    }
    /**
     * 当游戏管理员的消息发生变化时,通知所有已经注册的游戏玩家
     * @param message
     */
    public void setGameMessage(String message){
        this.message = message;
        notifyAllGamePlayer();
    }
}
4)具体观察者
public class GamePlayer implements IGamePlayer {
    private String name;
    public GamePlayer(String name) {
        this.name = name;
    }
    public void updateMessage(String message) {
        System.out.println(name + " 收到游戏管理员消息:" + message);
    }
}
5)测试类
public class Test {
    public static void main(String[] args){
        IGameAdmin iGameAdmin = new GameAdmin();
        IGamePlayer iGamePlayer1 = new GamePlayer("张三");
        IGamePlayer iGamePlayer2 = new GamePlayer("李四");
        IGamePlayer iGamePlayer3 = new GamePlayer("王五");
        iGameAdmin.addGamePlayer(iGamePlayer1);
        iGameAdmin.addGamePlayer(iGamePlayer2);
        iGameAdmin.addGamePlayer(iGamePlayer3);
        System.out.println("游戏发生了故障");
        iGameAdmin.setGameMessage("游戏维护中,2小时后恢复");
        iGameAdmin.removeGamePlayer(iGamePlayer2);
        System.out.println("游戏恢复后");
        iGameAdmin.setGameMessage("游戏恢复正常,可以游戏了");
    }
}
游戏发生了故障
张三 收到游戏管理员消息:游戏维护中,2小时后恢复
李四 收到游戏管理员消息:游戏维护中,2小时后恢复
王五 收到游戏管理员消息:游戏维护中,2小时后恢复
游戏恢复后
张三 收到游戏管理员消息:游戏恢复正常,可以游戏了
王五 收到游戏管理员消息:游戏恢复正常,可以游戏了
java常用设计模式四:观察者模式的更多相关文章
- java常用设计模式总览
		一.java的设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式. 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组 ... 
- 8.5 GOF设计模式四: 观察者模式Observer
		GOF设计模式四: 观察者模式Observer  现实中遇到的问题  当有许多不同的客户都对同一数据源感兴趣,对相同的数据有不同的处理方式,该如 何解决?5.1 定义: 观察者模式  观察者模式 ... 
- JAVA的设计模式之观察者模式----结合ActiveMQ消息队列说明
		1----------------------观察者模式------------------------------ 观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的 ... 
- JAVA常用设计模式(静态化调用和实例化调用的区别,编辑可见 )
		用newInstance()与用new是区别的,区别在于创建对象的方式不一样,前者是使用类加载机制,后者是创建一个新类,且newInstance()只能调用无参构造函数. 最大的区别在于内存.静态方法 ... 
- Java常见设计模式之观察者模式
		在阎宏博士的<JAVA与模式>一书中开头是这样描述观察者(Observer)模式的: 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Mo ... 
- JAVA基础——设计模式之观察者模式
		观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式.源-监听器(Source/Listener)模式或从属者(Dependen ... 
- Java设计模式16:常用设计模式之观察者模式(行为型模式)
		1. Java之观察者模式(Observer Pattern) (1)概述: 生活中我们在使用新闻app,当我们对某一栏比较感兴趣,我们往往会订阅这栏新闻,比如我对军事栏感兴趣,我就会订阅军事栏的新闻 ... 
- java常用设计模式
		一个程序员对设计模式的理解: "不懂"为什么要把很简单的东西搞得那么复杂. 后来随着软件开发经验的增加才开始明白我所看到的"复杂"恰恰就是设计模式的精髓所在,我 ... 
- JAVA常用设计模式整理
		设计模式:一个程序员对设计模式的理解:“不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开一把 ... 
随机推荐
- java类封装成dll
			@参考文章1,@参考文章2,@参考文章3 1,建立测试类,注意英文注释部分,用汉语直接编译会乱码 public class Hello { //native method is used for ca ... 
- 日志排序(gets函数与sscanf的使用)
			题目链接:https://www.nowcoder.com/practice/0f64518fea254c0187ccf0ea05019672?tpId=40&tqId=21363&t ... 
- php使用fputcsv进行大数据的导出
			为了实验大数据的导出,我们这里先自已创建一张大表,表结构如下: CREATE TABLE `tb_users` ( `id` int(11) unsigned NOT NULL AUTO_INCREM ... 
- C#实现发送给QQ邮件
			最近在做一个通过点击忘记密码往用户邮箱中发邮件(邮件内容是一个超链接)点击进行修改的功能,发送原理,我们只是把邮件发送给smtp服务器,然后再由smtp服务器发送到邮箱,发送之前要校验一下. 1.微软 ... 
- vs的【warning C4996:'fopen': This function or variable may be unsafe】解决方案
			编译警告:warning C4996 与 Security Enhancements in the CRT 将过去的工程用VS2005打开的时候.你有可能会遇到一大堆的警告:warning C4996 ... 
- RabbitMQ 的基本介绍
			RabbitMQ官网教程:http://www.rabbitmq.com/getstarted.html RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现.AMQP :Adv ... 
- tableView上出现空白的解决办法
			创建tableView后,出现如下效果 解决办法: self.automaticallyAdjustsScrollViewInsets = NO; 个人认为,应该是取消系统默认行为,保证界 ... 
- python爬虫 urllib库基本使用
			以下内容均为python3.6.*代码 学习爬虫,首先有学会使用urllib库,这个库可以方便的使我们解析网页的内容,本篇讲一下它的基本用法 解析网页 #导入urllib from urllib im ... 
- mysql 查两个表之间的数据差集
			需要查两个表之间的差集 首先,想到的是主键直接not in select mailbox_id from co_user where mailbox_id not in (select mailbox ... 
- android Run模式也会出现"Waiting for debugger"的解决方法
			android Run模式也会出现"Waiting for debugger"的解决方法 出现“waiting for debugger”窗口是在debug模式下运行出现的.但是, ... 
