MVC设计问题

发布于 2024-11-01 04:14:50 字数 533 浏览 0 评论 0原文

请注意,我是 MVC 新手。

我正在努力使我的代码尽可能地解耦和可测试。 我有一个带有文本框和按钮的视图。 我想在输入新文本时启用该按钮并遵守特定标准。

理想情况下,我希望这个逻辑能够决定按钮是否在视图之外启用,以便可以对其进行单元测试。

我对MVC的理解是这样的: 在我看来,我有一个对我的控制器的引用。 在我的控制器中,我引用了我的模型。 在我的模型中,我引用了我的视图。

你能告诉我下面这个设计是否好? 我向模型 ButtonEnabled 添加了一个布尔值。 事件的顺序是这样的: 在文本框中输入文本,文本框有一个监听器。监听器调用控制器上的textChanged方法,控制器检查是否启用按钮,然后通过setButtonEnabled访问器设置模型的buttonEnabled。 访问器更改buttonEnabled的值,并在视图上调用buttonEnabledChanged()(公开该方法) 这个想法是视图是模型的特定观察者,而模型是一个可观察的,理论上可以有多个视图,并且可以对所有视图调用buttonEnabledChanged()。

请告诉我您的想法。

Just a note, I'm new to MVC.

I'm trying to make my code as much decoupled and testable as possible.
I have a view with a text box and button.
I want to enable the button when a new text is entered and respects a certain criteria.

Ideally, I'd like this logic that decides if the button is enabled or not outside the view so it can be unit tested.

My understanding of MVC goes like that:
In my View I have a reference to my Controller.
In my Controller I have a reference to my Model.
In my Model I have a reference to my View.

Can you tell me if the following is a good design.
I added a boolean to the model buttonEnabled.
the sequence of event is like that:
Text is input in the text box, the text box has a listener. The listener calls a textChanged method on the Controller, the controller does the checks on whether to enable the button or not, and then sets the buttonEnabled of the Model through a setButtonEnabled accessor.
The accessor changes the value of buttonEnabled, and calls a buttonEnabledChanged() on the view (which exposes that method)
the idea is that the view is specific observer of the model, and the model is an observable which could theoretically have multiple views, and can call buttonEnabledChanged() on all of them.

Please let me know what you think.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你的呼吸 2024-11-08 04:14:50

这是对哲学问题的哲学回答:)

你的建议可能是正确的。但真正的问题是 buttonEnabled 是否真的适合您的模型。这纯粹是 gui 的事情,在那里没有任何意义。真正特定于接口的东西属于视图,而不是其他地方。

现在可能有一个原因导致该按钮被禁用(例如,输入无效)。然后您可以在模型中为其指定另一个名称 (isValid)。从 !isValid!buttonEnabled 的转换将成为控制器的一部分,甚至是视图本身的一部分。

但我猜测,在您的情况下,在没有内容时阻止按钮的唯一原因是使用户不太可能以空白表单发送。在这种情况下,我会完全执行签入视图(如果是网络,则使用 JavaScript),只是为了用户方便。在模型中,如果空字符串无论如何都到达那里,则只需抛出异常(IllegalArgumentException 似乎很可能)。

如果您正在对模型进行单元测试,那么测试它是否会抱怨空字符串,然后检查您的模型是否将 buttonEnabled 设置为 false 更有意义。如果你真的想测试 GUI 功能,有一些解决方案(对于 Web,我想到的是 selenium)。

This is a philosophical answer to a philosophical question :)

What you suggest could be correct. But the real question is if buttonEnabled is really a good candidate for your model. It's a purely gui thing and makes no sense being there. Thing that are really specific to the interface belong in the view, and nowhere else.

Now there might be a reason that the button is disabled (like, entry is not valid). Then you could just give it another name in the model (isValid). The translation from !isValid to !buttonEnabled would then become part of the controller, or even the view itself.

But I'm guessing that, in your case, the only reason to block the button when there is no content is to make it less likely for the user to send in a blank form. In that case, I would do the check in view completely (javascript if it's web), just for user convenience. In the model, just throw an exception (IllegalArgumentException seems likely) if the empty string gets there anyway.

If you're unit-testing your model, it makes a lot more sense to test if it will complain about an empty string, then to check if your model is setting buttonEnabled to false. If you really want to test gui functionality, there are solutions for that (for web, selenium comes to mind).

颜漓半夏 2024-11-08 04:14:50

您的建议过于复杂,而且在我看来,从 MVC 的角度来看是错误的。

  • 控制器不应该检查是否启用按钮,这是模型的任务。
  • 模型不应调用视图上的任何方法。
  • 你的方法太具体了。这种只更新特定内容的愿望,例如 ButtonEnabledChanged() 将使将来的事情变得过于复杂,其中组件通过某些业务逻辑相互依赖。

您需要的是将此文本框的值绑定到模型值,也许通过控制器。因此,更改文本框的值将更改模型的值。然后它应该调用视图上的更新。视图知道模型中存在一些属性来确定是否应启用按钮。它不应该被称为 isButtonEnabled(),因为它与视图无关。它应该被称为 isTextMatchingCriteria 或其他名称。根据该属性的值,视图决定是否启用该按钮。

这样:

  • 控制器仅控制。它是捕获、委托、更新,但不决定业务逻辑上的任何内容。
  • 该模型独立于视图。
  • View没有任何可以单独调用的特定方法。它唯一能做的就是根据模型的当前状态呈现正确的演示。它还指定模型的一种或另一种状态在屏幕上的含义 - 禁用按钮或错误消息。模型不应该这样做。

What you suggest is overcomplicated and, in my opinion, wrong from the standpoint of MVC.

  • The controller should not check whether or not to enable button, it is the task of model.
  • The model should not call any methods on view.
  • You have too specific methods. This desire to update only specific stuff, like buttonEnabledChanged() will make things overcomplicated in future, where components depend on each other through some business logic.

What you need is to bind this text box's value to model value, perhaps through the controller. So, changing text boxes value will change model's value. It should then call the update on the view. The view knows, that in the model there is some property that determines if the button should be enabled. It shouldn't be called isButtonEnabled() because it is agnostic of the view. It should be called isTextMatchingCriteria or something. Based on the value of that property, the view decides whether to enable the button or not.

This way:

  • Controller only controlls. It is catches and delegates, updates, but doesn't decide anything on business logic.
  • The model is independent of view.
  • View doesn't have any specific methods that can be called separately. The only thing it can is to render a correct presentation based on the current state of the model. It also specifies, what one or another state of the model mean on the screen - a disabled button or error message. The model shouldn't do that.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文