使用表示模型处理父表单子表单关系的最佳实践
根据 Martin Fowler 的演示模型注释以及有关演示模型的 MSDN 文档,解释了演示模型类应该不知道 UI 类,类似地,业务模型类应该不知道演示模型类。
UI 应广泛地将数据绑定到表示模型,表示模型又将与一个或多个域/业务模型对象协调以完成工作。表示模型基本上以一种有利于 UI 中最大数据绑定的方式呈现域模型数据,允许 UI 做出尽可能少的决策,从而提高表示行为的可测试性。这也使得表示模型类变得通用,即与任何特定的 UI 技术无关。
现在,考虑有一个列表表单(例如 CustomerList)和另一个根表单(例如 Customer),并且有一个用例允许通过单击按钮从 CustomerList 表单编辑客户。
为了简化讨论,请考虑当从菜单打开客户列表(即单击客户菜单)时发生了一些操作,并且客户列表已从菜单单击事件显示。
现在,根据上述用例,我需要从客户列表中打开客户根 UI(单个客户)。我该怎么做?
在“编辑”按钮的单击事件中构建必要的对象(BusinessModel、PresentationModel、UI)并从那里调用 CustomerEdit UI?
从演示模型类构建 CustomerEdit UI 并从演示模型显示 UI? 这可以通过以下两种方式中的任何一种来完成 - 一个。按照以下顺序创建对象 DomainModel->PresentationModel-UIForm b.使用 Unity.Resolve(); 无论哪种方式,都会违反表示模型,因为 P 模型现在必须引用 CustomerEdit 所在的具体 UI 程序集。此外,P 模型必须直接引用和使用 WinForm,从而减少 UI 技术的不可知性。
尽管这些违规行为在理论上是可以忽略的,但我仍然会寻求社区的意见,看看我是否走错了方向。请建议是否有更好的方法从列表(父)表单中调用子表单。
- 拉贾尔希
According to Presentation Model notes by Martin Fowler and also on MSDN documentation about Presentation Model, it is explained that the Presentation Model Class should be unaware of the UI class and similarly Business Model Class should be unaware of the Presentation Model class.
The UI should databind extensively to the Presentation Model, the Presentation Model in turn will co-ordinate with one or more Domain/Business Model objects to get the job done. The Presentation Model basically presents the Domain Model data in a way to facilitate maximum data binding in UI, allowing the UI take as less decisions as possible and thus increase testability of Presentation behaviours. This also makes the presentation model class generic, i.e. agnostic of any particular UI technology.
Now, consider there is a List form (say CustomerList) and there is another Root form (say Customer) and there is a Use Case of allowing to Edit a Customer from the CustomerList form on a button click.
For simplicity of discussion, consider that some actions took place when Customer List is opened from menu (i.e. Customer menu clicked) and the Customer List has been shown from the Menu click event.
Now as per the above Use Case, I need to open the Customer Root UI (single Customer) from the Customer List. How do I do that?
Build necessary objects (BusinessModel, PresentationModel, UI) in click event of Edit button and call CustomerEdit UI from there?
Build the CustomerEdit UI from Presentation Model Class and show UI from presentation model?
this can be done in any of the two ways below -
a. Create objects in the following sequence DomainModel->PresentationModel-UIForm
b. Use Unity.Resolve();
Either ways, Presentation Model is violated as the P model now has to the refer the concrete UI assembly, where CustomerEdit is located. Also the P Model has to refer and use a WinForm directly making it less UI technology agnostic.
Even though the violations are in theory and can be ignored, I would still seek the community's opinion about whether I am going wrong direction. Please suggest if there's a better way to call the Child Form from the List (Parent) Form.
- Rajarshi
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的目标通常是系统不同部分之间的松散耦合,以便更容易维护。例如,这意味着您的模型不应该知道它所通信的确切类型。它应该只知道所需的接口。
当您的模型引用 UI 或业务逻辑层中的某些内容时,只要它使用接口而不是特定类型进行操作,就没有什么不好或奇怪的。
Your aim is usually the loose coupling between different parts the system for that sake of easier maintainability. This means that your model, for example, should not know that exact types it communicates with. It should know only about required interfaces.
There is nothing bad or strange when your model references something in your UI or in business logic layer, as long as it operates with interfaces instead of specific types.
如何将 IEditCustomerService 注入到 CustomerList 的PresentationModel 中,以便在编辑所选客户时调用该模型。然后,该服务要么自行“构建必要的对象”,要么将此任务委托给 IViewManagerService,该服务知道哪些 UI 可用于编辑实体、哪一个应该用于特定实体,以及如何构建帽子 UI 组件。当然,您也可以通过将 IViewManagerService 直接注入到PresentationModel 中来避免一种间接方式,或者您可以使用 DI 容器来解决它。
另一种可能性是让 IViewManagerService 实现侦听由 CustomerList 的PresentationModel 触发的EditCustomerEvents。
what about injecting a IEditCustomerService into the CustomerList's PresentationModel, which is invoked in case a selected Customer should be edited. This service then either does "build the necessary objects" itself, or it delegaes this task to a IViewManagerService, which knows what UIs are available to edit entities, which one should be used for a specific one, and how to build up hat UI component. Of course you could also avoid one indirection by injecting the IViewManagerService directly into the PresentationModel, or you could use an DI container to resolve it.
Another possibility would be to let an IViewManagerService implementation listen for EditCustomerEvents fired by the CustomerList's PresentationModel.