将 MVC 模式应用到现有应用程序
这是MVC 模式和 SWING 的后续问题。我正在尝试在现有代码段中实现 MVC 模式。现有代码创建一个 JFrame,它既充当视图又充当控制器。 JFrame 有一个表,该表的模型是自定义数据模型的适配器。每当用户执行操作时,模型都会通过执行以下操作来更新:
CustomDataTableModel cdtm = (CustomDataTableModel) DataTable.getModel();
CustomDataModel cdm = cdtm.getModel();
cdm.delete(1);
我尝试可视化它当前的工作方式,但我也可视化了我想象的与未来控制器和模型的关系应该如何。
现在,我的问题是我是否可以继续使用现在的模型?我可以实现以下内容并仍然“遵守”MVC 模式吗?
- 用户选择表中的一个元素,然后单击删除按钮。
- 视图将操作委托给控制器。
- 控制器通过视图上的访问器访问表,并执行更新。
- 模型更新时会通知 JTable 它已更改。
如果视图中的任何其他组件显示表中的数据,则可以通过在 JTable 的表模型上注册侦听器来解决此问题。
更新 1
我一直在根据 MVC 模式思考现有代码,并且我重新绘制了一些关系。要点是控制器是视图的行为,因此当用户执行操作时控制器会更新模型,而视图会侦听模型中的更改。但是,MVC 模式中没有任何内容可以阻止视图通过表模型监听模型 - 对吗?
现在,用户单击添加按钮。视图通知控制器已单击添加按钮,控制器通过调用模型上的某些方法来创建新项目。视图注册为模型上的侦听器(通过表模型)并更新其视图。控制器也可以是模型上的侦听器,以防它需要处理禁用或锁定字段。难道我还没有实现 MVC 的全部意义吗?关注点分离?据我所知,我什至引入了适配器模式来将视图与模型进一步解耦?已经很晚了,我很累,所以这可能就是为什么它有意义:-)
This is a follow up question to The MVC pattern and SWING. I am trying to implement the MVC pattern in an existing piece of code. The existing code creates a JFrame which acts as both the view and the controller. The JFrame has a table, and the table's model is an adapter to a custom data model. Whenever the user performs an action, the model would be updated by doing something like the following:
CustomDataTableModel cdtm = (CustomDataTableModel) DataTable.getModel();
CustomDataModel cdm = cdtm.getModel();
cdm.delete(1);
I've tried to visualise how it currently works, but I've also visualised how I imagine the relationships with the future controller and model should be.
Now, my question is simply whether I can continue using the model as it is now? Could I implement the following and still "adhere" to the MVC pattern?
- The user selects an element in the table, and clicks on a delete button.
- The view delegates the action to the controller.
- The controller access the table through an accessor on the view, and performs the update.
- The model, when it is updated, notifies the JTable that it has been changed.
If any other components in the view displays data from the table, then this could be solved by registering listeners on the JTable's table model.
Update 1
I've been thinking about the existing code in light of the MVC pattern, and I've redrawn the relationships a little. The point is that the controller is the behaviour of the view, thus the controller updates the model when users do stuff, and the view listens for changes in the model. However, nothing in the MVC pattern stops the view from listening to the model through a tablemodel - right?
Now, the user clicks the add button. The view notifies the controller that the add button has been clicked, and the controller takes care of creating a new item by invoking some method on the model. The view is registered as a listener on the model (through a table model) and updates its view. The controller may also be a listener on the model in case it needs to take care of disabling or locking fields. Have I not achieved what the MVC is all about; separation of concerns? As far as I can see, I've even introduced the adapter pattern to decouple the view even more from the model? It is late and I am tired, so that might be why it makes sense :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一般来说,我会建议您以下几点:
它不是 MVC 但使用
“PresentationModel”模式
在我看来,这是更好的
适应整个应用程序比
MVC(我发现适合
仅个别小部件)。这应该
解决你们之间的问题
域模型和 TableModel(
那么 GlazedLists 也制作了
很有道理:它也会隔离
你的领域模型
TableModel(但它不强制
任何全局模式,MVC 或 PM)
关于您展示的当前设计,我宁愿建议 View 向 Controller 请求一个
Action
查看将分配给删除按钮。然后控制器可以作用于域模型。In the general sense, I would advise you the following:
it is not MVC but uses the
"PresentationModel" pattern
which is, in my opinion, better
adapted to a whole application than
MVC (which I find suitable for
individual widgets only). This should
solve your problem between your
Domanin Model and the TableModel
then GlazedLists also makes a
lot of sense: it will also isolate
your Domain Model from your
TableModel (but it doesn't enforce
any global pattern, MVC or PM)
Regarding the current design you show, I would rather suggest that the View asks the Controller for an
Action
that the View will assign to the Delete button. Then the Controller can act on the Domain Model.唉,这很快就会变得混乱和混乱,而且由于缺乏分离,代码库已经很混乱了。
我建议将不同的组件迁移到干净、简单的 MVC 设计。这样的组件(目前是视图、控制器和模型混合在一起)将以干净的方式分离,但是您会遇到如何处理控制器和模型的困难?
作为临时解决方法,您将被迫将所有者视图指定为控制器,因此所有者可能承担更多责任。我认为这是一个合适的解决方法,因为您最终会将越来越多的组件分离到 MVC 设计中,并且同时也是控制器的视图最终也会被重构。
换句话说:
请小心确保应用程序在上述每个“步骤 4”结束时仍能正常工作,否则,您会发现自己陷入混乱,而且修复时间会越来越长。 (即使最终结果干净整洁,您也可能错过了最后期限)。
请记住,一开始从代码中提取“模型”可能很困难 - 控制器和视图将最容易分离,但最终,模型也将变得更容易分离。每当您设法提取模型时,请编写单元测试来单独测试该模型。
一套编写良好的单元测试的存在将有助于确保应用程序继续具有明确定义的关注点分离。 (如果关注点没有分离,那么单元测试就变得非常困难),因此单元测试方法可以作为动力。
我希望这是有道理的。
That gets messy and confusing fast, alas, and the code base is already confusing due to lack of separation.
I suggest instead migrating distinct components to a clean, simple MVC design. Such a component (which is currently a view, controller, and model all mixed up together) would then be separated in a clean fashion, however you will then have the difficulty of how to handle the controller and model?
As a temporary workaround, you'll be forced to designate the owner view as the controller, so the owner arguably has more responsibility. I think that this is a suitable workaround, because you will eventually separate more and more components into an MVC design, and the views that are also controllers will eventually become refactored as well.
In other words:
Be careful to ensure that the application is still working at the end of every 'step 4' above, otherwise, you'll find yourself in a mess that just gets longer and longer to fix. (Even if the end result is nice and clean, you may have missed your deadline).
Keep in mind that it may be difficult to extract the 'model' from the code at first - the controllers and views will be easiest to separate, but eventually, the models will become easier to separate as well. Whenever you manage to extract a model, write unit tests that test that model in isolation.
The presence of a well written suite of unit tests will help ensure that the application continues to have well-defined separation of concerns. (If concerns are not separated, then it becomes very hard to unit test), so the unit testing approach serves as a motivator.
I hope that makes sense.