重新分解为MVC模式 - 对视图与控制器分离的疑虑

vol*_*ing 6 python model-view-controller user-interface wxpython

我试图将我的应用程序(具有1000多行GUI代码)重构为MVC样式模式.逻辑代码已经与GUI分离,因此这不是问题.我关心的是从控制器中分离出来的观点.我理解MVC的基本原理和wxpython wiki中的这个教程非常有用,但是代码示例有点简单,当我尝试将主体应用到我自己的项目时这让我很怀疑,这个项目要复杂得多.

一个结构的片段..

我有MainWindow一些小部件,包括一个noteBook(选项卡式部分),noteBook有许多选项卡其中一个选项卡(我调用FilterTab)包含一个类的两个实例(我称之为FilterPanel),这是一个带有列表框的面板,三个按钮,一个清除,一个删除,一个添加项目到列表中.根据实例化时传递给类的标志,add按钮事件可以创建不同类型的对话框,例如文本输入对话框或directoryPicker等.

这只是GUI的一部分,它非常分层 - 事件处理程序隐藏在FilterPanel类中.

如果我要将该部分转换为MVC,我将必须为我的控制器中的FilterPanel的每个实例(而不是filterPanel类)绑定按钮事件 - 在这种情况下有两个(filterPanel实例)

所以我会为每个按钮(每个filterPanel 3个按钮*面板实例的数量)加上处理程序这样的东西.

 self.mainWindow.filterTab.dirFilterPnl.Bind(wx.EVT_BUTTON,
                                    self.onAdd_dirFilterPnl, 
                            self.mainWindow.filterTab.dirFilterPnl.addBtn,
                            self.mainWindow.filterTab.dirFilterPnl.addBtn.GetId()
                                    )
Run Code Online (Sandbox Code Playgroud)

这增加了很多额外的代码,(如果我只有两个filterPanel实例,事件处理程序的数量加倍)

所以我想知道我采取了正确的方法吗?

Ale*_*lli 9

如果我要将该部分转换为MVC,我将必须为我的控制器中的FilterPanel的每个实例绑定按钮事件(而不是在filterPanel类中)

不必要!MVC的理念和实践并不意味着"观点"是基本的小部件; 您FilterPanel可以被认为/实现为"丰富/复合"小部件,它生成自己的,更高级别的"事件"(指向控制器)并进行适当更新.因此,该复合窗口小部件可以具有较低级别"事件"的处理程序,并从它们合成更高级别的事件,将它们发送到控制器; 控制器不必知道或关心每个按钮等,只是关于它接收的更高抽象事件,例如"用户想要为目的X选择目录"或"用户想要为目的Y输入文本" - 通过告诉视图该做什么来回应他们.

关键点在于视图不会根据它处理的事件做出"语义"决策,也不会向模型发送任何命令 - 控制器是所有此类交互不可或缺的"中间人".

作为类比,考虑GUI的最低层具有非常低级别的事件,例如"鼠标左键"和"鼠标左键" - "按钮小部件"通过更改按钮的外观直接对它们做出反应(a "视觉"决定,而不是"战略"决定)并且最终,如果适当的话,合成一个更高抽象的事件,例如"按下按钮"(当鼠标按钮按下后,鼠标按钮向上,没有中间鼠标移动例如,使"点击"假设无效.然后将后者引导到需要"响应"按钮点击的任何更高层.

类似地,您的rich/composite小部件可以接受此类事件并合成更高抽象的小部件,以便控制器做出反应.(可以通过按钮单击,菜单选择,某些击键来生成相同的抽象事件......控制器不关心这些低层"视觉"注意事项,即视图/窗口小部件的工作,以及视图/窗口小部件没有将"战略"决策和行动硬编码到这种用户交互,这是控制器的工作.

关注点的分离有助于解决测试和应用程序灵活性等问题; 这并不是闻所未闻的,因为这些优势是以更多代码的价格购买的,所有代码都是硬编码的......但是如果你选择MVC,你就意味着价格,对你来说,非常值得付出代价.

wx可能不是实现它的理想框架,但是您可以将wx.Event子类 - 或者您可以使用单独的事件系统(如pydispatcher)来处理在不同子系统之间流动的更高抽象事件,以便将控制器与特定子系统分离GUI框架的选择.我通常使用Qt,其信号/插槽模型IMNSHO比典型的GUI框架的事件系统更好地扩展/扩展.但是,这是一个不同的选择和另一个问题.

  • @volting,不客气!在列表框中仅显示每个项目一次,就像(比方说)是否按照添加顺序或以某种排序顺序显示项目一样,我通常将其归类为视觉决策 - 没有硬性和快速的决定标准,但在我看来,它实际上是一个关于"如何向用户展示"事物的决定,而不是"要执行什么语义动作". (2认同)