Java设计模式之从[星际争霸的兵种升级]分析观察者(Observer)模式
观察者模式定义对象的一种一对多的依赖关系。当一个对象的状态发生改变时。全部依赖于它的对象都会得到通知并被自己主动更新。
一个简单的样例是。在星际争霸的虫族中有一个0基础单位叫做跳狗(Zergling),玩家能够在研究中心为它升级“肾上腺素”,升级之后,跳狗的攻击速度会翻倍。在这个模型中,我们能够看出。全部的跳狗都依赖于研究中心,当研究中心研究出肾上腺素后,通知每个跳狗单位,它们被迫进行自我更新——升级速度加倍。在观察者模型中。我们称研究中心为目标(Subject),而跳狗为观察者(Observer)。观察者观察目标的变化,假设目标发生了变化,那么观察者自身也会跟着变化。
下面是Java代码:
import java.util.ArrayList;
abstract class Subject{
    ArrayList<Observer> observers = new ArrayList<Observer>();
    public void attach(Observer observer){
        if (!observers.contains(observer))
            observers.add(observer);
    }
    public void detach(Observer observer){
        if (observers.contains(observer))
            observers.remove(observer);
    }
    protected void notifyObservers(){
        for (Observer o : observers){
            o.update(this);
        }
    }
}
abstract class Observer{
    Subject subject;
    public Observer(Subject subject){
        this.subject = subject;
        subject.attach(this);
    }
    abstract void update(Subject subject);
}
class AdrenalUpgrade extends Subject{
    public void upgrade(){
        notifyObservers();
    }
}
class Zergling extends Observer {
    public Zergling(Subject subject) {
        super(subject);
    }
    public void update(Subject subject) {
        if (subject == this.subject){
            System.out.println("Zergling的肾上腺素被刺激,攻击速度翻倍。");
        }
    }
}
public class ObserverExample
{
    public static void main(String[] args) {
        AdrenalUpgrade adrenalUpgrade = new AdrenalUpgrade();
        Zergling z1 = new Zergling(adrenalUpgrade);
        Zergling z2 = new Zergling(adrenalUpgrade);
        Zergling z3 = new Zergling(adrenalUpgrade);
        Zergling z4 = new Zergling(adrenalUpgrade);
        Zergling z5 = new Zergling(adrenalUpgrade);
        Zergling z6 = new Zergling(adrenalUpgrade);
        Zergling z7 = new Zergling(adrenalUpgrade);
        adrenalUpgrade.upgrade();
    }
}
Subject的是目标的基类,它能够attach或detach一个Observer。Subject含有一个List用于记录自己被哪些Observer依赖。当自身的状态改变时。会依次调用每个Observer的update()方法。
比如在main方法中,我们分别建立了z1、z2……z7共7个Zergling单位,它们都attach到了AdrenalUpgrade上,当AdrenalUpgrade调用了upgrade()时,会给每个Zergling发出通知,因此程序的执行结果为:
Zergling的肾上腺素被刺激,攻击速度翻倍!
Zergling的肾上腺素被刺激,攻击速度翻倍!
Zergling的肾上腺素被刺激,攻击速度翻倍!
Zergling的肾上腺素被刺激。攻击速度翻倍。
Zergling的肾上腺素被刺激。攻击速度翻倍!
Zergling的肾上腺素被刺激,攻击速度翻倍。
Zergling的肾上腺素被刺激,攻击速度翻倍。
以上就是观察者模式的一个样例。有兴趣的同学能够看一看MVC(C#)结构。它可能是观察者模式中最有名的结构之中的一个了。
Java设计模式之从[星际争霸的兵种升级]分析观察者(Observer)模式的更多相关文章
- Java 实现观察者(Observer)模式
		1. Java自带的实现 类图 /** * 观察目标 继承自 java.util.Observable * @author stone * */ public class UpdateObservab ... 
- Head First 设计模式 —— 02. 观察者 (Observer) 模式
		思考题 在我们的一个实现中,下列哪种说法正确?(多选) P42 public class WeatherDate { // 实例变量声明 public void measurementsChanged ... 
- 面向对象设计模式——观察者(OBSERVER)模式
		定义 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. Observer模式描述了如何建立这种关系.这一模式中的关键对象是目标(subject ... 
- 设计模式之观察者(OBSERVER)模式
		定义 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. Observer模式描述了如何建立这种关系.这一模式中的关键对象是目标(subject ... 
- java观察者(Observer)模式
		观察者模式: 试想,在电子商务网站上,一个用户看中了一件一份,但是当时衣服的价格太贵,你需要将衣服收藏,以便等衣服降价时自动通知该用户.这里就是典型的观察模式的例子. 1.观察者模式的 ... 
- 《Head First 设计模式》ch.2 观察者(Observer)模式
		观察者模式 定义了对象之间一对多以来,这样一来,当一个对象改变状态时,它所有的依赖者都会收到通知并自动更新 设计原则-松耦合 松耦合将对象之间的互相依赖降到了最低——只要他们之间的接口仍被遵守 观察者 ... 
- 设计模式C++描述----04.观察者(Observer)模式
		一. 概述 Observer 模式要解决的问题为:建立一个一(Subject)对多(Observer)的依赖关系,并且做到当“一”变化的时候,依赖这个“一”的多也能够同步改变. Sbuject 相当于 ... 
- 20. 星际争霸之php设计模式--适配器模式
		题记==============================================================================本php设计模式专辑来源于博客(jymo ... 
- 17. 星际争霸之php设计模式--职责链模式
		题记==============================================================================本php设计模式专辑来源于博客(jymo ... 
随机推荐
- POJ 3253 STL优先队列
			题目大意:FJ需要修补牧场的围栏,他需要 N 块长度为 Li 的木头(N planks of woods).开始时,FJ只有一块无限长的木板,因此他需要把无限长的木板锯成 N 块长度 为 Li 的木板 ... 
- 可变长度参数列表(Stering...aaa)
- Entity Framework -- 添加,删除,修改,关系依附,关系摘除,验证操作
			数据库模型 这个基本上是浓缩 Jerry Tom博客的内容,作为参考http://www.cnblogs.com/mbailing/archive/2012/07/31/2616779.html 说明 ... 
- [跨域]js设置document.domain实现跨域
			document.domain用来得到当前网页的域名.比如在地址栏里输入: 代码如下: javascript:alert(document.domain); //www.jb51.net 我们也可以给 ... 
- 【C++】cin、cout的效率比scanf和printf低的解决方法
			玩竞赛的同学应该发现了C++中直接调用cout.cin的效率要比printf和scanf的效率要低. 要解决这个问题,只需要在前面加上一句 std::ios::sync_with_stdio(fals ... 
- SQL Server存储过程作业(三)
			阶段4:练习——插入入住客人记录 需求说明 使用存储过程将入住客人信息插入客人信息表中,要求: 检查身份证号必须是18个字符组成 押金的默认值为1000元 如果客人记录插入成功,输出客人流水号:否则输 ... 
- 浅谈Java三大框架与应用
			前言:对于一个程序员来说,尤其是在java web端开发的程序员,三大框架:Struts+Hibernate+Spring是必须要掌握熟透的,因此,下面谈谈java三大框架的基本概念和原理. JAVA ... 
- .Net并行计算支持嵌套事务的方法
			问题背景 一年前,我们开始利用.Net 4.0的TPL(Task Parallel Library)并行计算技术对复杂计算的功能节点进行性能优化,这些复杂计算往往会包含大量对数据库的操作.在应用TPL ... 
- jquery Contains 实现查询
			var filter = $(this).val(); var filterResult = $(this).find('h2:Contains(' + filter + ')'); if (filt ... 
- springboot 大致启动流程
			SpringApplication的run方法的实现是我们本次旅程的主要线路,该方法的主要流程大体可以归纳如下: 1) 如果我们使用的是SpringApplication的静态run方法,那么,这个方 ... 
