【设计模式】发布订阅001

本文介绍了一个使用Java实现的发布-订阅模式示例,涉及实体类如DesUser和DesPC,事件类DesEvent,以及订阅者MyListener、传播者MyTransporter和发布者MyPublisher的交互过程。

模型

请添加图片描述

思路

发布者 和 订阅者,引入传播器将事件从发布者传递通知到订阅者。

例如当前有事件event, 有事件体 user、PC。 发布者 负责发起 一系列消息。订阅者各自订阅需要的消息。由传播者将消息传播下去。

示例

实体类
public class DesUser {
  private String userName;
  private Long userId;

  public DesUser(String userName, Long userId) {
    this.userName = userName;
    this.userId = userId;
  }

  @Override
  public String toString() {
    return "DesUser{" + "userName='" + userName + '\'' + ", userId=" + userId + '}';
  }

  public String getUserName() {
    return userName;
  }

  public void setUserName(String userName) {
    this.userName = userName;
  }

  public Long getUserId() {
    return userId;
  }

  public void setUserId(Long userId) {
    this.userId = userId;
  }
}

public class DesPC {

  private String brand;

  private String shape;

  @Override
  public String toString() {
    return "DesPC{" + "brand='" + brand + '\'' + ", shape='" + shape + '\'' + '}';
  }

  public DesPC(String brand, String shape) {
    this.brand = brand;
    this.shape = shape;
  }

  public String getBrand() {
    return brand;
  }

  public void setBrand(String brand) {
    this.brand = brand;
  }

  public String getShape() {
    return shape;
  }

  public void setShape(String shape) {
    this.shape = shape;
  }


}

事件类
public class DesEvent<T> {

  public T dto;

  public String message;

  public DesEvent(T dto, String message) {
    this.dto = dto;
    this.message = message;
  }

  public T getDto() {
    return dto;
  }

  @Override
  public String toString() {
    return "DesEvent{" + "dto=" + dto + ", message='" + message + '\'' + '}';
  }

  public void setDto(T dto) {
    this.dto = dto;
  }

  public String getMessage() {
    return message;
  }

  public void setMessage(String message) {
    this.message = message;
  }
}
订阅者

@Slf4j
public class MyListener<T> {

  private Class<T> classType;

  public MyListener(Class<T> classType) {
    this.classType = classType;
  }

  public boolean canSub(DesEvent<?> event) {
    return event.dto.getClass().isAssignableFrom(classType);
  }

  public void subMessage(DesEvent<?> event) {
    log.info("subMessage:, dto:{}, message:{}", event.getDto(), event.getMessage());
  }

}
传播者
public class MyTransporter {

  private List<MyListener<?>> myListeners = new ArrayList<>();

  public void register(MyListener<?> myListener) {
    myListeners.add(myListener);
  }

  public void tellListeners(DesEvent<?> event) {
    for (MyListener<?> myListener : myListeners) {
      if (myListener.canSub(event)) {
        myListener.subMessage(event);
      }
    }
  }
}

发布者
public class MyPublisher {

  public MyPublisher(MyTransporter myTransporter) {
    this.myTransporter = myTransporter;
  }

  private final MyTransporter myTransporter;

  public void push(DesEvent<?> event) {
    System.out.println("push event..." + event);
    myTransporter.tellListeners(event);
  }

}

主程序

public class PubSubMain {
  public static void main(String[] args) {
    MyListener<DesUser> myListener = new MyListener<DesUser>(DesUser.class);
    MyListener<DesPC> myListener2 = new MyListener<DesPC>(DesPC.class);
    MyListener<DesUser> myListener3 = new MyListener<DesUser>(DesUser.class);

    MyTransporter myTransporter = new MyTransporter();
    myTransporter.register(myListener);
    myTransporter.register(myListener2);
    myTransporter.register(myListener3);

    MyPublisher myPublisher = new MyPublisher(myTransporter);
    myPublisher.push(new DesEvent<>(new DesUser("张山", 1L), "user数据"));
    myPublisher.push(new DesEvent<>(new DesPC("华为", "荣耀"), "pc数据"));
  }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值