java订阅发布案例,结合观察者模式

应用场景:

     用java写一个服务端程序,可以接受订阅和取消订阅,或拉取,和主动推送。初步一想,似乎很简单,但做成容易扩展和类似框架结构,就没那么随意设计了。当然,本人也是个新手,阅读了设计模式一书中的观察者模式,不断写一些小demo,为了充分理解面向接口面层,也是从定义顶层接口入手了。

功能说明:

  贴测试类代码了。注释很明白了。

 
public static void main(String[] args) {
    //init register
    //1.currentTObserverdisplyTObserver两个观察者(客户端)    CurrentTObserver currentTObserver=new CurrentTObserver("CurObserver1");
    DisplyTObserver displyTObserver=new DisplyTObserver("DisObserver");

    //2.两个观察者(客户端)订阅了不同类型,品种的数据。currentTObserver订阅了两种个容器的数据,另外一个只订阅了天气容器中的数据。
    WeatherSubjectContainer.getInstance().registerObserver(currentTObserver);
    WeatherSubjectContainer.getInstance().registerObserver(displyTObserver);
    CarSubjectContainer.getInstance().registerObserver(currentTObserver);

    //3.WeatherSubjectContainerCarSubjectContainer两种数据发生了改变的时候,调用自己的dateChange方法,两个客户端就可以收到对应数据了。
    //4.扩展数据品种增加一个container,增加一种数据类型即可。
    int te = 1;
    int hum = 3;
    while (true) {
        try {
            Thread.sleep(1000);
            System.out.println(" data rescore push data ...");
            te++;
            hum++;
            WeaterDate weaterDate = new WeaterDate("WD_DATA");
            weaterDate.setTemperature(te);
            weaterDate.setHumidity(hum);
            WeatherSubjectContainer.getInstance().dateChange(weaterDate);

            CarDate carDate = new CarDate("CAR_DATA");
            carDate.setCarNum("CarA0000");
            carDate.setCarStatus("");
            CarSubjectContainer.getInstance().dateChange(carDate);
            //模拟取消订阅
            if (te>5){
                WeatherSubjectContainer.getInstance().rmoveObserver(currentTObserver);
            }
            System.out.println("WE->"+WeatherSubjectContainer.getInstance().getMapSize());
            System.out.println("Cr->"+CarSubjectContainer.getInstance().getMapSize());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
 

1.项目结构:

2.结构说明:

core包中包括两个顶层接口,一个主题抽象类,数据的抽象类,基类,观察者的基类。所有的相关的新写的对象都要继承或实现其中的特有方法。model包中定义数据具体类,继承BaseDate,observer包中是所有观察者,自己定义,需要继承BaseTobserver类。subject包中就是数据容器了。数据添加进容器不在这里讨论了。

3.核心如下代码:其中没使用到的方法和接口中的内容是为了扩展应用。实际是用不到可以削减方法。后面的subject和model,就看实际业务数据怎么样就怎么写了。做好继承就行。观察者的话,接收到数据分类处理即可。

public abstract class BaseDate {
    private String dataId;

    public BaseDate(String dataId) {
        this.dataId = dataId;
    }

    public String getDataId() {
        return dataId;
    }

    public void setDataId(String dataId) {
        this.dataId = dataId;
    }
}
public abstract class BaseToserver implements TObserver {
    private String observerId;


    public BaseToserver(String observerId) {
        this.observerId = observerId;
    }

    public abstract void update(BaseDate baseDate);

    public abstract void init(BaseDate baseDate);

    public String getObserverId() {
        return observerId;
    }

    public void setObserverId(String observerId) {
        this.observerId = observerId;
    }
}
public abstract class Subject implements TObservable {
    public static Logger LOG = LoggerFactory.getLogger(Subject.class);

    private BaseDate data;
    private ConcurrentHashMap<String, BaseToserver> submap = new ConcurrentHashMap<>();

    @Override
    public void registerObserver(BaseToserver o) {

        submap.put(o.getObserverId(), o);

    }

    @Override
    public void rmoveObserver(BaseToserver o) {
        if (submap.containsKey(o.getObserverId())) {
            submap.remove(o.getObserverId());
        } else {
            LOG.error(" remove failed " + o.getObserverId());
        }

    }

    @Override
    public void notifyObsevers() {
        Set<Map.Entry<String, BaseToserver>> entrySet = submap.entrySet();
        for (Map.Entry<String, BaseToserver> entry : entrySet
                ) {
            entry.getValue().update(data);
        }
    }

    @Override
    public void dateChange(BaseDate o) {
        this.data = o;
        notifyObsevers();
    }

    public int getMapSize() {
        return submap.size();
    }
}
public interface TObservable {
    public void registerObserver(BaseToserver o);

    public void rmoveObserver(BaseToserver o);

    public void notifyObsevers();

    public void dateChange(BaseDate o);
}
public interface TObserver<T> {
    public void TestHandle();
}
 
public class CarDate extends BaseDate{
    public CarDate(String dateId) {
        super(dateId);
    }
    private String carNum;
    private String carStatus;

    public String getCarNum() {
        return carNum;
    }

    public void setCarNum(String carNum) {
        this.carNum = carNum;
    }

    public String getCarStatus() {
        return carStatus;
    }

    public void setCarStatus(String carStatus) {
        this.carStatus = carStatus;
    }
}

 
public class CurrentTObserver extends BaseToserver {


    public CurrentTObserver(String observerId) {
        super(observerId);
    }

    @Override
    public void update(BaseDate baseDate) {

        if (baseDate instanceof WeaterDate) {
            WeaterDate date = (WeaterDate) baseDate;
            System.out.println(" Current observer receive WeaterDate-> " + date.getHumidity() + "-" + date.getTemperature());
        } else if (baseDate instanceof CarDate) {
            CarDate carDate = (CarDate) baseDate;
            System.out.println(" Current observer receive carDate> " + carDate.getCarNum() + "-" + carDate.getCarStatus());
        }

    }

    @Override
    public void init(BaseDate BaseDate) {

    }

    @Override
    public void TestHandle() {

    }
}

public class CarSubjectContainer extends Subject{
    private static WeatherSubjectContainer ourInstance = new WeatherSubjectContainer();

    public static WeatherSubjectContainer getInstance() {
        return ourInstance;
    }
}

4.总结:根据设计模式和合理使用抽象类的编程设计,还是第一次从这种角度去考虑。感觉很不错。模型有了,解读源码和框架就更舒服了。观察者和数据类型完整代码资料下载地址:https://download.csdn.net/download/flybridy/10460374



  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值