设计模式之观察者模式(Observe)-泛型扩展

设计模式之观察者模式(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();
    }

泛型做的是类型限制
类图
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tcoding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值