你说得对,让我重新审视整个事件系统的设计哲学。当前设计确实有些"过度工程化"了。
🤔 核心问题分析
看你的事件列表,我发现了一个模式:
// 大部分事件都是"生命周期钩子"
ServerStarting, ServerStarted, ServerStopping, ServerStopped
MiddlewareExecuting, MiddlewareExecuted
HandlerExecuting, HandlerExecuted
SubAppExecuting, SubAppExecuted本质: 你需要的是 Hook 系统 + 少量事件,而不是把所有东西都建模成事件。
方案1: Hook + Event 混合架构 (推荐)
// ============ Hooks (同步、顺序、无冒泡) ============
class Hooks {
private val hooks = ConcurrentHashMap<String, CopyOnWriteArrayList<(Any?) -> Unit>>()
fun on(name: String, handler: (Any?) -> Unit) {
hooks.computeIfAbsent(name) { CopyOnWriteArrayList() }.add(handler)
}
fun trigger(name: String, data: Any? = null) {
hooks[name]?.forEach { it(data) }
}
// 便捷方法
inline fun <reified T> onTyped(name: String, noinline handler: (T) -> Unit) {
on(name) { data ->
if (data is T) handler(data)
}
}
}
// ============ Events (异步、可冒泡、复杂逻辑) ============
sealed class AppEvent(val bubbles: Boolean = true) {
var source: Colleen? = null
internal set
var currentTarget: Colleen? = null
internal set
@Volatile
private var _stopped = false
val isStopped get() = _stopped
fun stopPropagation() { _stopped = true }
}
// 只保留真正需要"事件特性"的
class ExceptionThrown(val exception: Exception, val ctx: Context) : AppEvent()
class RequestTransform(val request: Request, var transform: ((Request) -> Request)? = null) : AppEvent(false)
class ResponseTransform(val response: ResponseBody, var transform: ((ResponseBody) -> ResponseBody)? = null) : AppEvent(false)
// ============ Colleen ============
class Colleen {
val hooks = Hooks()
val events = EventBus(this)
fun start() {
hooks.trigger("server:starting")
// ... 启动逻辑
hooks.trigger("server:started")
}
internal fun executeMiddleware(ctx: Context, node: MiddlewareNode) {
hooks.trigger("middleware:before", MiddlewareContext(ctx, node))
val start = System.nanoTime()
// ... 执行逻辑
val duration = System.nanoTime() - start
hooks.trigger("middleware:after", MiddlewareContext(ctx, node, duration))
}
internal fun handleException(e: Exception, ctx: Context) {
// 错误才用事件(需要冒泡、可中断)
events.emit(ExceptionThrown(e, ctx))
}
}
// ============ 使用示例 ============
app.hooks.on("server:started") {
println("Server ready!")
}
app.hooks.onTyped<MiddlewareContext>("middleware:after") { ctx ->
if (ctx.duration > 1000) {
logger.warn("Slow middleware: ${ctx.node}")
}
}
app.events.on<ExceptionThrown> { event ->
// 可以 stopPropagation 阻止冒泡到父 App
logger.error("Error", event.exception)
event.stopPropagation()
}优势:
Hook 用于简单的生命周期回调(90%的场景)
Event 用于复杂的控制流(需要冒泡/拦截)
代码量减少 60%
性能更好(Hook 没有类型检查开销)
方案2: 纯函数式 Pipeline (最简洁)
// ============ 核心抽象 ============
typealias Hook<T> = (T) -> Unit
typealias Transform<T> = (T) -> T
typealias Interceptor<T> = (T, next: () -> Unit) -> Unit
class Pipeline<T> {
private val before = CopyOnWriteArrayList<Hook<T>>()
private val transforms = CopyOnWriteArrayList<Transform<T>>()
private val after = CopyOnWriteArrayList<Hook<T>>()
fun before(hook: Hook<T>) = before.add(hook)
fun transform(fn: Transform<T>) = transforms.add(fn)
fun after(hook: Hook<T>) = after.add(hook)
fun execute(initial: T, action: (T) -> Unit) {
var data = initial
// Before hooks
before.forEach { it(data) }
// Transforms
transforms.forEach { data = it(data) }
// Main action
action(data)
// After hooks
after.forEach { it(data) }
}
}
// ============ Colleen ============
class Colleen {
val serverLifecycle = Pipeline<Colleen>()
val requestPipeline = Pipeline<Request>()
val responsePipeline = Pipeline<ResponseBody>()
val middlewarePipeline = Pipeline<MiddlewareContext>()
val handlerPipeline = Pipeline<HandlerContext>()
// 错误用传统回调
private val errorHandlers = CopyOnWriteArrayList<(Exception, Context) -> Unit>()
fun onError(handler: (Exception, Context) -> Unit) = errorHandlers.add(handler)
fun start() {
serverLifecycle.execute(this) {
// 启动逻辑
}
}
internal fun handleRequest(request: Request) {
requestPipeline.execute(request) { transformedRequest ->
// 路由匹配、中间件执行等
}
}
}
// ============ 使用示例 ============
app.serverLifecycle.before {
println("Starting server...")
}
app.requestPipeline.transform { request ->
request.copy(headers = request.headers + ("X-Custom" to "value"))
}
app.middlewarePipeline.before { ctx ->
logger.info("Executing middleware: ${ctx.node.name}")
}
app.middlewarePipeline.after { ctx ->
logger.info("Middleware ${ctx.node.name} took ${ctx.duration}ms")
}
app.onError { e, ctx ->
logger.error("Request failed", e)
}优势:
最简洁(核心代码<50行)
类型安全的 Transform
无需定义几十个事件类
函数式,易测试
方案3: 观察者模式 + 拦截器链 (中庸)
// ============ 核心接口 ============
interface Lifecycle {
fun on(stage: String, handler: (Map<String, Any>) -> Unit)
fun trigger(stage: String, data: Map<String, Any> = emptyMap())
}
interface Interceptable<T> {
fun intercept(interceptor: (T, next: () -> T) -> T)
fun execute(value: T): T
}
// ============ 实现 ============
class SimpleLifecycle : Lifecycle {
private val handlers = ConcurrentHashMap<String, CopyOnWriteArrayList<(Map<String, Any>) -> Unit>>()
override fun on(stage: String, handler: (Map<String, Any>) -> Unit) {
handlers.computeIfAbsent(stage) { CopyOnWriteArrayList() }.add(handler)
}
override fun trigger(stage: String, data: Map<String, Any>) {
handlers[stage]?.forEach { it(data) }
}
}
class InterceptorChain<T> : Interceptable<T> {
private val interceptors = CopyOnWriteArrayList<(T, () -> T) -> T>()
override fun intercept(interceptor: (T, next: () -> T) -> T) {
interceptors.add(interceptor)
}
override fun execute(value: T): T {
var index = 0
fun next(current: T): T {
return if (index < interceptors.size) {
val interceptor = interceptors[index++]
interceptor(current) { next(current) }
} else {
current
}
}
return next(value)
}
}
// ============ Colleen ============
class Colleen : Lifecycle by SimpleLifecycle() {
val requestInterceptors = InterceptorChain<Request>()
val responseInterceptors = InterceptorChain<ResponseBody>()
fun start() {
trigger("before:start")
// 启动逻辑
trigger("after:start")
}
fun handleRequest(request: Request) {
trigger("request:received", mapOf("request" to request))
val transformed = requestInterceptors.execute(request)
// 处理逻辑
}
}
// ============ 使用 ============
app.on("before:start") {
println("Starting...")
}
app.requestInterceptors.intercept { request, next ->
val start = System.currentTimeMillis()
val result = next()
logger.info("Request took ${System.currentTimeMillis() - start}ms")
result
}
app.responseInterceptors.intercept { response, next ->
response.copy(headers = response.headers + ("Server" to "Colleen"))
}🎯 我的最终推荐: 方案1 (Hook + Event)
理由:
符合实际需求:
90% 的场景只需要简单的生命周期回调 → Hook
10% 需要复杂的事件传播(错误处理、子App通信) → Event
性能最优:
Hook 是字符串匹配,无反射
Event 只在必要时才有类型检查开销
API 最直观:
// 简单场景 app.hooks.on("server:started") { ... } // 复杂场景 app.events.on<ExceptionThrown> { event -> event.stopPropagation() }扩展性好:
Hook 可以动态添加新的生命周期点
Event 保留了完整的 OOP 能力
完整实现建议
// ============ Hooks (轻量级) ============
class Hooks {
private val handlers = ConcurrentHashMap<String, CopyOnWriteArrayList<(Any?) -> Unit>>()
fun on(name: String, handler: (Any?) -> Unit): () -> Unit {
val list = handlers.computeIfAbsent(name) { CopyOnWriteArrayList() }
list.add(handler)
return { list.remove(handler) } // 返回取消订阅函数
}
fun trigger(name: String, data: Any? = null) {
handlers[name]?.forEach {
try {
it(data)
} catch (e: Exception) {
logger.error("Hook $name failed", e)
}
}
}
}
// ============ Events (强类型、可控制) ============
sealed class AppEvent(val bubbles: Boolean = true) {
var source: Colleen? = null internal set
var currentTarget: Colleen? = null internal set
@Volatile private var _stopped = false
val isStopped get() = _stopped
fun stopPropagation() { _stopped = true }
}
// 只定义真正需要"事件特性"的
class ExceptionThrown(val exception: Exception, val ctx: Context) : AppEvent()
class RouteNotFound(val path: String, val ctx: Context) : AppEvent()
class EventBus(private val owner: Colleen) {
internal var parent: EventBus? = null
private val listeners = ConcurrentHashMap<Class<out AppEvent>, CopyOnWriteArrayList<(AppEvent) -> Unit>>()
inline fun <reified T : AppEvent> on(noinline handler: (T) -> Unit) {
listeners.computeIfAbsent(T::class.java) { CopyOnWriteArrayList() }
.add { if (it is T) handler(it) }
}
fun emit(event: AppEvent) {
if (event.source == null) event.source = owner
event.currentTarget = owner
listeners[event::class.java]?.forEach {
if (!event.isStopped) it(event)
}
if (event.bubbles && !event.isStopped) {
parent?.emit(event)
}
}
}
// ============ Colleen ============
class Colleen {
val hooks = Hooks()
val events = EventBus(this)
fun start() {
hooks.trigger("server:before-start")
// 启动逻辑
hooks.trigger("server:started")
}
internal fun executeMiddleware(ctx: Context, node: MiddlewareNode) {
hooks.trigger("middleware:before", MiddlewareContext(ctx, node))
val start = System.nanoTime()
try {
node.handler(ctx)
} catch (e: Exception) {
events.emit(ExceptionThrown(e, ctx))
}
hooks.trigger("middleware:after", MiddlewareContext(ctx, node, System.nanoTime() - start))
}
}
// 数据类
data class MiddlewareContext(
val ctx: Context,
val node: MiddlewareNode,
val duration: Long? = null
)你觉得这个方向如何?要不要我帮你重构整个事件系统?