设计模式之观察者模式(Observer)
本篇为 https://github.com/iluwatar/java-design-patterns/tree/master/observer 阅读笔记
扩展部分是很精彩
意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
场景
观测天气(机器观测,人工观测),天气变化时,观测者做相应的处理
天气观测示例
天气类型
public enum WeatherType {
SUNNY, RAINY, WINDY, COLD;
@Override
public String toString() {
return this.name().toLowerCase();
}
}
观测者接口
public interface WeatherObserver {
void update(WeatherType currentWeather);
}
天气类
public class Weather {
private WeatherType currentWeather;
private List<WeatherObserve> observes;
public Weather(){
currentWeather = WeatherType.SUNNY;
observes = new ArrayList<>();
}
public void addObserver(WeatherObserve observe){
observes.add(observe);
}
public void removeObserver(WeatherObserve observe){
observes.remove(observe);
}
public void timePassBy(){
WeatherType[] types = WeatherType.values();
currentWeather = types[(currentWeather.ordinal()+1)%types.length];
System.out.println(MessageFormat.format("The weather change to {0}",currentWeather));
notifyObservers();
}
private void notifyObservers(){
for (WeatherObserve observe : observes){
observe.update(currentWeather);
}
}
}
机器观测类
public class HobbitObserve implements WeatherObserve {
@Override
public void update(WeatherType currentWeather) {
switch (currentWeather) {
case COLD:
System.out.println("The hobbits are shivering in the cold weather.");
break;
case RAINY:
System.out.println("The hobbits look for cover from the rain.");
break;
case SUNNY:
System.out.println("The happy hobbits bade in the warm sun.");
break;
case WINDY:
System.out.println("The hobbits hold their hats tightly in the windy weather.");
break;
default:
break;
}
}
}
人工观测
public class OrcsObserve implements WeatherObserve{
@Override
public void update(WeatherType currentWeather) {
switch (currentWeather) {
case COLD:
System.out.println("The orcs are shivering in the cold weather.");
break;
case RAINY:
System.out.println("The orcs look for cover from the rain.");
break;
case SUNNY:
System.out.println("The orcs hobbits bade in the warm sun.");
break;
case WINDY:
System.out.println("The orcs hold their hats tightly in the windy weather.");
break;
default:
break;
}
}
}
测试
@Test
public void observeTest(){
Weather weather = new Weather();
weather.addObserver(new HobbitObserve());
weather.addObserver(new OrcsObserve());
weather.timePassBy();
weather.timePassBy();
weather.timePassBy();
weather.timePassBy();
weather.timePassBy();
}
类图
观测者模式扩展
使用泛型进行扩展
观察目标需继承此类
S:观测类 O:观察者类 A:观测参数
public abstract class Observable<S extends Observable<S,O,A>,O extends Observer<S,O,A>,A> {
protected List<O> observers;
public Observable(){
observers = new CopyOnWriteArrayList<>();
}
public void addObserver(O observer){
observers.add(observer);
}
public void remove(O observer){
observers.remove(observer);
}
public void notifyObserver(A arguments){
for (O observer : observers){
observer.update((S) this,arguments);
}
}
}
观察者接口
public interface Observer<S extends Observable<S,O,A>,O extends Observer<S,O,A>,A> {
void update(S subject,A argument);
}
天气观察者
public interface Race extends Observer<GWeather,Race,WeatherType> {
}
天气类
public class GWeather extends Observable<GWeather,Race,WeatherType> {
private WeatherType currentWeather;
public GWeather(){
currentWeather = WeatherType.SUNNY;
}
public void timePassBy(){
WeatherType[] enumsValues = WeatherType.values();
currentWeather = enumsValues[(currentWeather.ordinal()+1)%enumsValues.length];
System.out.println(MessageFormat.format("The weather change to {0}",currentWeather));
notifyObserver(currentWeather);
}
}
机器观察
public class GHobbitObserver implements Race {
@Override
public void update(GWeather subject, WeatherType currentWeather) {
switch (currentWeather) {
case COLD:
System.out.println("The hobbits are shivering in the cold weather.");
break;
case RAINY:
System.out.println("The hobbits look for cover from the rain.");
break;
case SUNNY:
System.out.println("The happy hobbits bade in the warm sun.");
break;
case WINDY:
System.out.println("The hobbits hold their hats tightly in the windy weather.");
break;
default:
break;
}
}
}
人工观察
public class GOrcsObserver implements Race {
@Override
public void update(GWeather subject, WeatherType currentWeather) {
switch (currentWeather) {
case COLD:
System.out.println("The orcs are shivering in the cold weather.");
break;
case RAINY:
System.out.println("The orcs look for cover from the rain.");
break;
case SUNNY:
System.out.println("The orcs hobbits bade in the warm sun.");
break;
case WINDY:
System.out.println("The orcs hold their hats tightly in the windy weather.");
break;
default:
break;
}
}
}
测试
@Test
public void genericTest(){
GWeather gWeather = new GWeather();
gWeather.addObserver(new GOrcsObserver());
gWeather.addObserver(new GHobbitObserver());
gWeather.timePassBy();
gWeather.timePassBy();
gWeather.timePassBy();
gWeather.timePassBy();
}
泛型做的是类型限制
类图