设计模式-数据总线模式
·
数据总线模式:(实际上,就是 Event-Bus 消息总线模式)允许在一个应用程序的组件之间收发消息/事件,而不需要这些组件相互感知,它们只需要知道所发送/接收的消息/事件的类型即可。
程序示例:
1.创建数据总线类、成员和数据类型接口
//成员
public interface Member extends Consumer<DataType>{
void accept(DataType dataType);
}
//数据类型
public interface DataType{
DataBus getDataBus();
void setDataBus(DataBus dataBus);
}
@Getter
@Setter
public abstract class AbstractDataType implements DataType{
private DataBus dataBus;
}
//总线
public class DataBus{
private static final DataBus INSTANCE = new DataBus();
private final Set<Member> listeners = new HashSet<>();
public static DataBus getInstance() {
return INSTANCE;
}
public void subscribe(final Member member) {
listeners.add(member);
}
public void unsubscribe(final Member member) {
listeners.remove(member);
}
public void publish(final DataType data) {
data.setDataBus(this);
listeners.forEach(x->x.accept(data));
}
}
2.创建具体的数据类型子类
@AllArgsConstructor
@Getter
public class MessageDataType extends AbstractDataType{
private final String message;
@Override
public String toString() {
return String.format("消息:{%s}",message);
}
public static DataType of(final String message) {
return new MessageDataType(message);
}
}
@RequiredArgsConstructor
@Getter
public class StartDataType extends AbstractDataType{
private final LocalDateTime when;
public static DataType of(final LocalDateTime time){
return new StartDataType(time);
}
}
@RequiredArgsConstructor
@Getter
public class StoppingData extends AbstractDataType{
private final LocalDateTime when;
public static DataType of(final LocalDateTime when) {
return new StoppingData(when);
}
}
3.创建具体成员
@Slf4j
public class MessageCollectorMember implements Member{
private final String name;
private final List<String> messges = new ArrayList<>();
public MessageCollectorMember(String name) {
this.name = name;
}
@Override
public void accept(final DataType dataType) {
if (dataType instanceof MessageDataType) {
handleEvent((MessageDataType) dataType);
}
}
//具体处理逻辑
private void handleEvent(MessageDataType data) {
log.info("{} sess message {}", name, data);
messges.add(data.getMessage());
}
public List<String> getMessges() {
return this.messges;
}
}
@Getter
@Slf4j
@RequiredArgsConstructor
public class StatusMember implements Member{
private final int id;
private LocalDateTime started;
private LocalDateTime stopped;
@Override
public void accept(final DataType dataType) {
if (dataType instanceof StartDataType) {
handleEvent((StartDataType) dataType);
}else if (dataType instanceof StoppingData){
handleEvent((StoppingData) dataType);
}
}
private void handleEvent(StartDataType data) {
started = data.getWhen();
log.info("接收方{}看到应用程序在{}启动",id,started);
}
private void handleEvent(StoppingData data){
stopped=data.getWhen();
log.info("接收方{}看到应用程序在{}停止",id,stopped);
log.info("接收方{}正在发送停止消息",id,stopped);
data.getDataBus().publish(MessageDataType.of(String.format("Goodbye cruel world from #%d!", id)));
}
}
测试输出:
DataBus bus = DataBus.getInstance();
bus.subscribe(new StatusMember(1));
bus.subscribe(new StatusMember(2));
MessageCollectorMember foo = new MessageCollectorMember("foo");
MessageCollectorMember boo = new MessageCollectorMember("boo");
bus.subscribe(foo);
bus.publish(StartDataType.of(LocalDateTime.now()));
bus.publish(MessageDataType.of("Only foo should see this"));
bus.subscribe(boo);
bus.publish(MessageDataType.of("Foo and boo should see this"));
bus.unsubscribe(foo);
bus.publish(MessageDataType.of("Only boo should see this"));
bus.publish(StoppingData.of(LocalDateTime.now()));
/*
接收方2看到应用程序在2023-01-06T17:42:12.456启动
接收方1看到应用程序在2023-01-06T17:42:12.456启动
foo sess message 消息:{Only foo should see this}
boo sess message 消息:{Foo and boo should see this}
foo sess message 消息:{Foo and boo should see this}
boo sess message 消息:{Only boo should see this}
接收方2看到应用程序在2023-01-06T17:42:12.466停止
接收方2正在发送停止消息
boo sess message 消息:{Goodbye cruel world from #2!}
接收方1看到应用程序在2023-01-06T17:42:12.466停止
接收方1正在发送停止消息
boo sess message 消息:{Goodbye cruel world from #1!}
*/
类图:

更多推荐



所有评论(0)