MVP模式中View和Presenter怎么解耦才不会互相引用?
我在用原生JS写一个简单的MVP架构,但发现View里要调用Presenter的方法,Presenter又要操作View的DOM,结果两边互相持有对方引用,感觉耦合太紧了。
比如我的View初始化时会this.presenter = new Presenter(this),而Presenter里又存了view实例去更新UI。这样真的符合MVP吗?有没有更干净的解耦方式?
我试过用事件监听,但逻辑一复杂就乱了。现在代码大概是这样:
class View {
constructor() {
this.presenter = new Presenter(this);
this.button = document.getElementById('btn');
this.button.addEventListener('click', () => {
this.presenter.handleButtonClick();
});
}
updateText(text) {
this.button.textContent = text;
}
}
class Presenter {
constructor(view) {
this.view = view;
}
handleButtonClick() {
this.view.updateText('Clicked!');
}
}
核心思路是把双向引用变成单向数据流:View只触发事件,Presenter监听事件并处理业务逻辑,然后通过事件通知View更新。这样两边都不会直接引用对方。
几点关键改进:
1. View和Presenter完全不知道对方的存在,只和事件总线交互
2. View负责渲染和事件触发,Presenter负责业务逻辑
3. 数据流动方向清晰:View -> Event -> Presenter -> Event -> View
比起你的原始方案,这种实现更符合MVP的核心思想,而且扩展性更好。如果后面要加新功能,只需要增加新的事件类型就行,不用改现有代码。