6 行为型模式-观察者模式

2021-08-17  本文已影响0人  格林哈

1 描述

2 模式原理分析

2.1 定义

3 使用场景

4 为什么使用观察者模式

5 优缺点

5.1 优点

5.2 缺点

6 总结

6 代码

6.1 jdk 支持

public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;
    
    public synchronized void addObserver(Observer o) {
    if (o == null)
        throw new NullPointerException();
    if (!obs.contains(o)) {
        obs.addElement(o);
      }
    }
    
    public void notifyObservers(Object arg) {

    Object[] arrLocal;

    synchronized (this) {

        if (!changed)
            return;
        arrLocal = obs.toArray();
        clearChanged();
    }

    for (int i = arrLocal.length-1; i>=0; i--)
        ((Observer)arrLocal[i]).update(this, arg);
    }
}
public interface Observer {
    void update(Observable o, Object arg);
}

6.2 模拟apollo 实现 一个配置文件改变,就改变读取了这个配置文件的客户端。

/**
 * Data class
 * 配置文件实体
 * @date 2021/8/17
 */
@Accessors(chain = true)
@lombok.Data
public class Data {
    private Long id;
    private String name;
    private String data;
}

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import java.util.Map;
import java.util.Observable;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
/**
 * DataSourcesCache class
 * 模拟定时读取某个文件,监控是否变化。
 * @date 2021/8/17
 */
@Slf4j
public class DataSourcesCache extends Observable {
    public static Map<String,Data>  cache = new ConcurrentHashMap<>();

    public  void init(){
        ThreadFactory threadFactory = new BasicThreadFactory.Builder().namingPattern("DataSourcesCache-%s").daemon(true).build();
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2 , threadFactory);
        scheduledThreadPoolExecutor.scheduleWithFixedDelay(()->{
            Random random = new Random();
            Long i = random.nextLong();
            Data data = new Data();
            data.setId(i).setName("name" + i).setData("data" + i);

            String key = random.nextInt(2) == 1 ?  "gelin" : "gelin1" ;

            cache.put(key,data);

            super.setChanged();
            super.notifyObservers(key);
            log.info("change {} data {}",key, JSON.toJSONString(data));
        },5,5, TimeUnit.SECONDS);
    }
}
import com.alibaba.fastjson.JSON;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.Observable;
import java.util.Observer;
/**
 * DataSourcesClient class
 * 客户端读取配置文件
 * @date 2021/8/17
 */
@Data
@Slf4j
public class DataSourcesClient implements Observer {
    private String name;
    private com.designPatterns.observer.apollo.Data data;
    @Override
    public void update(Observable o, Object arg) {
        if(arg instanceof String) {
            String key = (String) arg;
            if(key.equals(name)){
                data = DataSourcesCache.cache.get(arg);
                log.info("name: {}, change : {}", name,JSON.toJSONString(data));
            }

        }
    }
}
public class Main {
    public static void main(String[] args) {
        // 配置数据来源 通过定时刷新
        DataSourcesCache dataSourcesCache = new DataSourcesCache();
        dataSourcesCache.init();


        DataSourcesClient dataSourcesClient = new DataSourcesClient();
        dataSourcesClient.setName("gelin");

        DataSourcesClient dataSourcesClient2 = new DataSourcesClient();
        dataSourcesClient2.setName("gelin1");

        dataSourcesCache.addObserver(dataSourcesClient);
        dataSourcesCache.addObserver(dataSourcesClient2);
        synchronized (Main.class) {
            try {
                Main.class.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

16:57:44.754 [DataSourcesCache-1] INFO com.designPatterns.observer.apollo.DataSourcesClient - name: gelin1, change : {"data":"data-7371821606940861810","id":-7371821606940861810,"name":"name-7371821606940861810"}
16:57:44.757 [DataSourcesCache-1] INFO com.designPatterns.observer.apollo.DataSourcesCache - change gelin1 data {"data":"data-7371821606940861810","id":-7371821606940861810,"name":"name-7371821606940861810"}
16:57:49.763 [DataSourcesCache-1] INFO com.designPatterns.observer.apollo.DataSourcesClient - name: gelin1, change : {"data":"data-5749414509503057278","id":-5749414509503057278,"name":"name-5749414509503057278"}
16:57:49.763 [DataSourcesCache-1] INFO com.designPatterns.observer.apollo.DataSourcesCache - change gelin1 data {"data":"data-5749414509503057278","id":-5749414509503057278,"name":"name-5749414509503057278"}
16:57:54.769 [DataSourcesCache-2] INFO com.designPatterns.observer.apollo.DataSourcesClient - name: gelin, change : {"data":"data-6057120240679674117","id":-6057120240679674117,"name":"name-6057120240679674117"}
16:57:54.769 [DataSourcesCache-2] INFO com.designPatterns.observer.apollo.DataSourcesCache - change gelin data {"data":"data-6057120240679674117","id":-6057120240679674117,"name":"name-6057120240679674117"}

参考

上一篇下一篇

猜你喜欢

热点阅读