设计模式学习笔记——观察者(Observer)模式
@(设计模式)[设计模式, 观察者模式, Observer]
基本介绍
观察者模式也称为发布-订阅模式。
在观察者订阅被观察者发布的内容时,所订阅的内容发生变化,观察者会接到相应通知。观察者可以进行相应处理。
观察者案例
类图
实现代码
Observer接口
package com.pc.observer.example;
/**
* 观察者接口
* Created by Switch on 2017/3/30.
*/
public interface Observer {
/**
* 更新
*
* @param generator 数值生成器
*/
void update(NumberGenerator generator);
}
DigitObserver类
package com.pc.observer.example;
/**
* 数字观察者对象
* Created by Switch on 2017/3/30.
*/
public class DigitObserver implements Observer {
@Override
public void update(NumberGenerator generator) {
System.out.println("DigitObserver:" + generator.getNumber());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
GraphObserver类
package com.pc.observer.example;
/**
* 图形观察者类
* Created by Switch on 2017/3/30.
*/
public class GraphObserver implements Observer {
@Override
public void update(NumberGenerator generator) {
System.out.print("GraphObserver:");
for (int i = 0; i < generator.getNumber(); i++) {
System.out.print("*");
}
System.out.println();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
NumberGenerator抽象类
package com.pc.observer.example;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 数值生成器抽象类
* Created by Switch on 2017/3/30.
*/
public abstract class NumberGenerator {
/**
* 观察者列表
*/
private List<Observer> observers = new ArrayList<>();
/**
* 添加观察者
*
* @param observer 观察者对象
*/
public void addObserver(Observer observer) {
observers.add(observer);
}
/**
* 删除指定观察者
*
* @param observer 观察者对象
*/
public void deleteObserver(Observer observer) {
observers.remove(observer);
}
/**
* 向观察者列表中的所有观察者发送通知
*/
public void notifyObservers() {
Iterator<Observer> it = observers.iterator();
while (it.hasNext()) {
Observer observer = it.next();
observer.update(this);
}
}
/**
* 获取数值
*
* @return 数值
*/
public abstract int getNumber();
/**
* 生成数值
*/
public abstract void execute();
}
RandomNumberGenerator类
package com.pc.observer.example;
import java.util.Random;
/**
* 随机数值生成器类
* Created by Switch on 2017/3/30.
*/
public class RandomNumberGenerator extends NumberGenerator {
/**
* 随机数生成器
*/
private Random random = new Random();
/**
* 当前数值
*/
private int number;
@Override
public int getNumber() {
return this.number;
}
@Override
public void execute() {
for (int i = 0; i < 20; i++) {
number = random.nextInt(50);
this.notifyObservers();
}
}
}
测试类
package com.pc.observer.example.test;
import com.pc.observer.example.*;
import org.junit.Test;
/**
* DigitObserver Tester.
*
* @author Switch
* @version 1.0
*/
public class ObserverTest {
/**
* 测试观察者模式
*/
@Test
public void testObserver() {
NumberGenerator generator = new RandomNumberGenerator();
Observer observer1 = new DigitObserver();
Observer observer2 = new GraphObserver();
generator.addObserver(observer1);
generator.addObserver(observer2);
generator.execute();
}
}
运行结果
DigitObserver:15
GraphObserver:***************
DigitObserver:43
GraphObserver:*******************************************
DigitObserver:17
GraphObserver:*****************
DigitObserver:21
GraphObserver:*********************
DigitObserver:12
GraphObserver:************
DigitObserver:15
GraphObserver:***************
DigitObserver:11
GraphObserver:***********
DigitObserver:34
GraphObserver:**********************************
DigitObserver:0
GraphObserver:
DigitObserver:37
GraphObserver:*************************************
DigitObserver:12
GraphObserver:************
DigitObserver:38
GraphObserver:**************************************
DigitObserver:22
GraphObserver:**********************
DigitObserver:30
GraphObserver:******************************
DigitObserver:1
GraphObserver:*
DigitObserver:28
GraphObserver:****************************
DigitObserver:44
GraphObserver:********************************************
DigitObserver:45
GraphObserver:*********************************************
DigitObserver:23
GraphObserver:***********************
DigitObserver:45
GraphObserver:*********************************************
观察者模式中的角色
Subject(观察对象)
Subject
角色表示观察对象。Subject
角色定义了注册观察者和删除观察者的方法。此外,它还声明了“获取现在的状态”的方法。在案例中,由NumberGenerator
类扮演此角色。
ConcreteSubject(具体的观察对象)
ConcreteSubject
角色表示具体的被观察对象。当自身状态发生变化后,它会通知所有已经注册的Observer
角色。在案例中,由RandomNumberGenerator
类扮演此角色。
Observer(观察者)
Observer
角色负责接收来自Subject
角色的状态变化的通知。为此,它声明了update
方法。在案例中,由Observer
接口扮演此角色。
ConcreteObserver(具体的观察者)
ConcreteObserver
角色表示具体的Observer
。当它的update
方法被调用后,会去获取要观察的对象的最新状态。在案例中,由DigitObserver
类和GraphObserver
类扮演此角色。
类图
GitHub:DesignPatternStudy
——————参考《图解设计模式》