You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合Guice重构处理Update/Delete事件的Listener类

可行重构方案(结合Guice与Listener模式)

方案1:抽象类模板方法+Guice多绑定+事件分发器

这个方案既保留了抽象类的共享逻辑复用,又解决了多实现的绑定问题,同时让每个子类只专注处理自己的事件类型。

1. 重构抽象类(模板方法模式)

把通用逻辑(依赖注入、事件类型判断框架、日志)放在抽象类中,子类仅实现特定事件的支持判断与处理逻辑:

public abstract class DocumentListener implements Listener {
    // 共享的注入依赖
    protected final Logger LOGGER;
    protected final Phase phase_;

    @Inject
    public DocumentListener(Logger LOGGER, Phase phase_) {
        this.LOGGER = LOGGER;
        this.phase_ = phase_;
    }

    // 通用receive方法,负责路由事件到子类处理
    @Override
    public final void receive(Event event) {
        if (supports(event)) {
            handleEvent(event);
        } else if (event instanceof PhaseEvent) {
            // 通用空处理逻辑
        } else {
            LOGGER.warn("Received unknown event type : " + event.getClass().getName());
        }
    }

    // 子类实现:判断是否支持当前事件
    protected abstract boolean supports(Event event);

    // 子类实现:处理支持的事件
    protected abstract void handleEvent(Event event);
}

2. 实现子类

分别编写处理Update和Delete事件的子类:

// Update事件处理子类
public class DocumentUpdateListener extends DocumentListener {
    // 注入自身额外依赖(如果需要)
    @Inject
    public DocumentUpdateListener(Logger LOGGER, Phase phase_, /* 其他专属依赖 */) {
        super(LOGGER, phase_);
    }

    @Override
    protected boolean supports(Event event) {
        return event instanceof UpdateEvent;
    }

    @Override
    protected void handleEvent(Event event) {
        UpdateEvent updateEvent = (UpdateEvent) event;
        // 原2000行代码中的Update处理逻辑
    }
}
// Delete事件处理子类
public class DocumentDeleteListener extends DocumentListener {
    @Inject
    public DocumentDeleteListener(Logger LOGGER, Phase phase_, /* 其他专属依赖 */) {
        super(LOGGER, phase_);
    }

    @Override
    protected boolean supports(Event event) {
        return event instanceof EntityDeleteEvent;
    }

    @Override
    protected void handleEvent(Event event) {
        EntityDeleteEvent deleteEvent = (EntityDeleteEvent) event;
        // 原2000行代码中的Delete处理逻辑
    }
}

3. Guice绑定与事件分发

使用Guice的多绑定功能,将两个子类注册为Listener集合,再创建一个分发器统一接收事件并路由到对应子类:

// 事件分发器
public class DocumentEventDispatcher implements Listener {
    private final Set<Listener> documentListeners;

    @Inject
    public DocumentEventDispatcher(Set<Listener> documentListeners) {
        this.documentListeners = documentListeners;
    }

    @Override
    public void receive(Event event) {
        for (Listener listener : documentListeners) {
            listener.receive(event);
        }
    }
}
// Guice模块配置
public class DocumentModule extends AbstractModule {
    @Override
    protected void configure() {
        // 绑定两个子类到Listener集合
        Multibinder<Listener> listenerBinder = Multibinder.newSetBinder(binder(), Listener.class);
        listenerBinder.addBinding().to(DocumentUpdateListener.class).in(SINGLETON);
        listenerBinder.addBinding().to(DocumentDeleteListener.class).in(SINGLETON);

        // 绑定分发器为对外提供的统一Listener(用命名注解区分)
        bind(Listener.class)
            .annotatedWith(Names.named("DocumentEventDispatcher"))
            .to(DocumentEventDispatcher.class)
            .in(SINGLETON);
    }
}

原调用方只需注入@Named("DocumentEventDispatcher") Listener即可接收事件,分发器会自动将事件路由到对应的处理子类。


方案2:独立Listener实现+Guice多绑定

如果两个事件的处理逻辑共享代码极少,可以去掉抽象类,让两个子类直接实现Listener接口,通过Guice多绑定注册所有实现:

public class DocumentUpdateListener implements Listener {
    @Inject
    public DocumentUpdateListener(/* 所有依赖 */) {}

    @Override
    public void receive(Event event) {
        if (event instanceof UpdateEvent) {
            // Update处理逻辑
        } else if (event instanceof PhaseEvent) {
            // 空处理
        } else {
            LOGGER.warn("Received unknown event type : " + event.getClass().getName());
        }
    }
}
public class DocumentDeleteListener implements Listener {
    @Inject
    public DocumentDeleteListener(/* 所有依赖 */) {}

    @Override
    public void receive(Event event) {
        if (event instanceof EntityDeleteEvent) {
            // Delete处理逻辑
        } else if (event instanceof PhaseEvent) {
            // 空处理
        } else {
            LOGGER.warn("Received unknown event type : " + event.getClass().getName());
        }
    }
}

Guice绑定:

public class DocumentModule extends AbstractModule {
    @Override
    protected void configure() {
        Multibinder<Listener> listenerBinder = Multibinder.newSetBinder(binder(), Listener.class);
        listenerBinder.addBinding().to(DocumentUpdateListener.class).in(SINGLETON);
        listenerBinder.addBinding().to(DocumentDeleteListener.class).in(SINGLETON);
    }
}

事件总线可以直接注入Set<Listener>来分发事件到所有实现类。


内容的提问来源于stack exchange,提问作者toy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 08:01:23