1. Observer模式
发送状态变化通知,当观察对象的状态发送变化时,会通知给观察者,Observer模式也被称为Publish-Subscribe(发布-订阅)。
1.1 Observer模式的类图
登场角色:
-
Subject(观察对象)
Subject角色定义了注册观察者和删除观察者的方法 -
ConcreteSubject(具体的观察对象)
具体的观察对象 -
Observer(观察者)
负责接收来自Subject角色的状态变化通知 -
ConcreteObserver(具体的观察者)
具体的观察者
1.2 示例程序
类一览表:
名字 | 说明 |
---|---|
Observer | 观察者接口 |
NumberGenerator | 生成数字对象的抽象类 |
RandomNumberGenerator | 随机数生成类 |
DigitObserver | 以数字形式显示数值的类 |
GraphObserver | 以简单的图显示数值的类 |
Main | 测试类 |
uml类图
Observer接口
package xin.ajay.observer;
public interface Observer {
void update(NumberGenerator generator);
}
MumberGenerator类
package xin.ajay.observer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public abstract class NumberGenerator {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer){
observers.add(observer);
}
public void deleteObserver(Observer observer){
observers.remove(observer);
}
//通知
public void notifyObservers(){
for (Observer observer : observers) {
observer.update(this);
}
}
public abstract int getNumber();
public abstract void execute();
}
RandomNumberGenerator类
package xin.ajay.observer.impl;
import xin.ajay.observer.NumberGenerator;
import java.util.Random;
public class RandomNumberGenerator extends NumberGenerator {
private Random random = new Random();
private int number;
public int getNumber() {
return number;
}
@Override
public void execute() {
for (int i = 0; i < 20; i++) {
number = random.nextInt(50);
notifyObservers();
}
}
}
DigitObserver类
package xin.ajay.observer.impl;
import xin.ajay.observer.NumberGenerator;
import xin.ajay.observer.Observer;
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 xin.ajay.observer.impl;
import xin.ajay.observer.NumberGenerator;
import xin.ajay.observer.Observer;
public class GraphObserver implements Observer {
@Override
public void update(NumberGenerator generator) {
System.out.print("GraphObserver:");
int count = generator.getNumber();
for (int i = 0; i < count; i++) {
System.out.print("*");
}
System.out.println();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Main类
package xin.ajay.observer.impl;
public class Main {
public static void main(String[] args) {
RandomNumberGenerator generator = new RandomNumberGenerator();
generator.addObserver(new DigitObserver());
generator.addObserver(new GraphObserver());
generator.execute();
}
}
结果
DigitObserver: 13
GraphObserver:*************
DigitObserver: 32
GraphObserver:********************************
DigitObserver: 27
GraphObserver:***************************
DigitObserver: 42
GraphObserver:******************************************
DigitObserver: 40
GraphObserver:****************************************
DigitObserver: 16
GraphObserver:****************
DigitObserver: 23
GraphObserver:***********************
DigitObserver: 14
GraphObserver:**************
DigitObserver: 48
GraphObserver:************************************************
DigitObserver: 27
GraphObserver:***************************
DigitObserver: 38
GraphObserver:**************************************
DigitObserver: 13
GraphObserver:*************
DigitObserver: 36
GraphObserver:************************************
DigitObserver: 38
GraphObserver:**************************************
DigitObserver: 19
GraphObserver:*******************
DigitObserver: 4
GraphObserver:****
DigitObserver: 7
GraphObserver:*******
DigitObserver: 47
GraphObserver:***********************************************
DigitObserver: 36
GraphObserver:************************************
DigitObserver: 27
GraphObserver:***************************
鸣谢
GoF《设计模式》和结城浩的《图解设计模式》