草庐IT

python - Re-factoring To MVC pattern——view与controller分离的疑惑

coder 2023-08-26 原文

我正在尝试将我的应用程序(具有 1000 多行 GUI 代码)重构为 MVC 样式模式。 逻辑代码已经与 GUI 分开,所以这不是问题。我关心的是 View 与 Controller 的分离。我了解 MVC 的基本原理和 this tutorial wxpython wiki 中的内容非常有帮助,但代码示例有点简单,当我尝试将主体应用于我自己的项目时,这让我感到疑惑,这个项目要复杂得多。

结构片段..

我有一个 MainWindow,其中包含许多小部件,包括 noteBook(选项卡部分), noteBook 有许多选项卡,其中一个选项卡(我称之为 FilterTab)包含两个实例 类(我称之为 FilterPanel)是一个面板,带有一个列表框、三个按钮,一个用于清除,一个用于删除,一个用于添加项目到/从列表。取决于传递给的标志 实例化类添加按钮事件可以创建不同类型的对话框,例如文本输入对话框或目录选择器等。

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

如果我要将该部分转换为 MVC,我将不得不在我的 Controller 中(而不是在 filterPanel 类中)为 FilterPanel 的每个实例绑定(bind)按钮事件 - 在这种情况下有两个(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()
                                    )

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

所以我想知道我采取的方法是否正确?

最佳答案

If I were to convert that part to MVC I would have to bind the button events for each instance of the FilterPanel in my controller(instead of in the filterPanel class)

不一定! MVC 的理念和实践并不意味着“ View ”是基本的小部件;您的 FilterPanel 很可能被认为/实现为“丰富/复合”小部件,它生成自己的、更高级别的“事件”(定向到 Controller )并适当更新。因此,该复合小部件可以具有较低级别“事件”的处理程序,并从中合成较高级别的事件,并将它们发送到 Controller ; Controller 不必知道或关心每个按钮等,只需要知道它接收到的更高抽象事件,例如“用户想要为目的 X 选择目录”或“用户想要为目的 Y 输入文本” -- 并通过告诉 View 做什么来响应它们。

关键是 View 不会根据它处理的事件做出“语义”决定,也不会向模型发送任何命令—— Controller 是所有此类交互不可或缺的“中间人”。

打个比方,考虑 GUI 的最低层有非常低级别的事件,例如“按下鼠标左键”和“按下鼠标左键”——“按钮小部件”通过更改按钮的外观(“视觉”决定,而不是“战略”决定),并最终在适当的时候合成一个更高抽象的事件,例如“单击按钮”(当按下鼠标按钮后又按下鼠标按钮时,没有例如,中间鼠标移动使“点击”假设无效)。然后将后者定向到任何更高层需要“响应”按钮点击。

同样,您的丰富/复合小部件可以接收此类事件并合成更高抽象的事件,以便 Controller 使用react。 (同样的抽象事件可以通过按钮点击、菜单选择、某些击键产生…… Controller 不关心这些较低层的“视觉”考虑,这是 View /小部件的工作,而 View /小部件不会针对此类用户交互硬编码“战略”决策和操作,这是 Controller 的工作)。

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

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

关于python - Re-factoring To MVC pattern——view与controller分离的疑惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3271553/

有关python - Re-factoring To MVC pattern——view与controller分离的疑惑的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  3. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  4. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  5. ruby-on-rails - rails : How to make a form post to another controller action - 2

    我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak

  6. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  7. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  8. ruby-on-rails - 如何在 Rails Controller Action 上触发 Facebook 像素 - 2

    我有一个ruby​​onrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素

  9. ruby - Sinatra set cache_control to static files in public folder编译错误 - 2

    我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.

  10. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

随机推荐